Here’s some of the ugly details if you want to dig through the raw text of the problematic e-mail.
MIME is a standard for representing arbitrary data types in e-mail (also used for other Internet services). There are a few MIME types that are used to send mail with images embedded in the message:
multipart/mixed
This MIME type allows a single message to contain multiple items that are considered independent of each other. Like a message and some attachments. For example:
From: Me <me@example.com>
To: You <you@example.net>
Subject: Attachment
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=AnyArbitraryString
--AnyArbitraryString
Content-Type: text/plain
Hi. Here's a picture for you.
--AnyArbitraryString
Content-Type: image/jpeg; name="picture.jpg"
Content-Transfer-Encoding: base64
.... Lots of BASE64-encoded binary data ...
--AnyArbitraryString--
In the above example, the Content-Type
in the main header declares this as a multi-part message, which contains a mixture of different independent documents.
The boundary
is a string used to separate the parts from each other within the mail message. The string, when prefixed with --
indicates the start of a part (ending the previous part, if applicable) and the string, when also suffixed with --
indicates the end of all the parts. Although the string can be anything, most real-world e-mail software will generate a very long string containing some mix of keywords, random data and serial-number data, in order to ensure that it is unique and won’t ever appear within a part’s content. (If the boundary string appears within any part’s content, you’ll end up with a corrupt message.)
Each part may contain part-specific e-mail headers. In the above example, they identify the data type and (for the JPEG image) the way the binary data is encoded in the mail (since e-mail is a text-based medium).
multipart/alternative
This MIME type is meant for two parts that are meant to be alternative representations of the same content. It is usually used when sending HTML or rich-text format messages, in order to include a plain text version, so e-mail clients that don’t support HTML or rich text can display something useful to the reader. For example:
From: Me <me@example.com>
To: You <you@example.net>
Subject: Alternative mail
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary=myBoundary
--myBoundary
Content-Type: text/plain
Hi!. How are you doing?
--myBoundary
Content-Type: text/html
<HTML><BODY><P>
<B>Hi!.</B> How are you doing?
</P></BODY></HTML>
--myBoundary--
In the above example, the Content-Type
in the main header declares the message as having alternative representations.
Within each alternative are more headers (in this case, Content-Type
) identifying the format of the data. In the above example, there’s a plain-text version and an HTML version. The HTML version has some formatting. It could be any valid HTML document. An e-mail client is expected to choose the format it can best present and display it, and will normally not display the other alternatives unless explicitly told to do so (e.g. by a “View Original” button or menu item).
Note that while the alternatives should be variations on the same content, there’s nothing forcing them to be. For example, I’ve seen phishing e-mail where the plain-text version looks perfectly innocent, but the HTML version contains links to malware. Shenanigans like this can make it difficult to figure out what’s going on when problems occur. Fortunately, most legitimate mail-sending software doesn’t play games like that.
But that’s just how HTML mail is put together (at its simplest). In order to embed an attachment in the middle of an HTML message, we need to declare two parts as being related to each other, not separate independent or alternative parts. For this we have:
multipart/related
This tells the mail client that the two parts should be considered parts of a single item. Like an HTML file and an embedded image combine to form a single document. For example:
From: Me <me@example.com>
To: You <you@example.net>
Subject: Embedded
MIME-Version: 1.0
Content-Type: multipart/related; boundary=TheBoundary
--TheBoundary
Content-Type: text/html
<HTML><BODY><P>
Here's a picture for you: <IMG SRC="cid:picture.jpg" />
</P><P>
I hope you enjoy it.
</P></BODY></HTML>
--TheBoundary
Content-Type: image/jpeg; name="picture.jpg"
Content-Transfer-Encoding: base64
Content-ID: <picture.jpg>
.... Lots of BASE64-encoded binary data ...
--TheBoundary--
In this message, there are two related parts. One is an HTML message and the other is a JPEG image.
Note that the JPEG image has a Content-ID
header. This identifies the image. It is used by the HTML code via its cid:
URL, telling the HTML rendering engine to display the image at that place in the message.
Commonly, the message text is a multipart/alternative
part, not just HTML. So readers without HTML capability can see something. This isn’t a problem. When nesting one multipart document in another, software will use two different boundary strings, and this will let the recipient’s mail client know which parts go with which other parts.:
From: Me <me@example.com>
To: You <you@example.net>
Subject: Embedded with Alternative
MIME-Version: 1.0
Content-Type: multipart/related; boundary=Boundary1
--Boundary1
Content-Type: multipart/alternative; boundary=Boundary2
--Boundary2
Content-Type: text/plain
Here's a picture for you:
I hope you enjoy it
--Boundary2
Content-Type: text/html
<HTML><BODY><P>
Here's a picture for you: <IMG SRC="cid:picture.jpg" />
</P><P>
I hope you enjoy it.
</P></BODY></HTML>
--Boundary2--
--Boundary1
Content-Type: image/jpeg; name="picture.jpg"
Content-Transfer-Encoding: base64
Content-ID: <picture.jpg>
.... Lots of BASE64-encoded binary data ...
--Boundary1--
In the above example, we have three parts. Two alternatives containing the message body and a related part containing the image.
An HTML-capable mail viewer should display the HTML message, which will inline the related image via its cid:
URL. A non-HTML-capable viewer will display the plain text message and (hopefully) will provide a way to download the image as an attachment.
There are many other ways to do this, but the above examples should be enough to help you muddle through the guts of an e-mail’s raw content.
See also: