RFC 733 is one of the oldest and most fundamental RFCs.

It is the origin of the standard used today to construct internet email messages, RFC 5332.

This standard describes email messages consisting of two major sections :-

  • A Header, that describes information about the email. Fields such as From, To, CC etc.
  • A Body, that is essentially the content of the message to be sent.

The header and body must be separated by a null line and can only contain 7-bit ASCII characters.

So what does this have to do with MIME Multi-Part messages?

Restricting the message body to 7-bit ASCII characters limited the majority of messages to languages based on the Latin alphabet.

Multipurpose Internet Mail Extensions (MIME), RFC 2045 through RFC 2049, are a set of Internet Standards that layer additional formatting standards on the body section of an email.

To support :-

  • Text in character sets other than ASCII.
  • Non-text attachments.
  • Message bodies with multiple parts.

Ok so I know why MIME is used, but how are MIME Multi-Part Messages constructed?

MIME Headers

MIME defines additional header lines that inform the receiving client about how the body should be interpreted.

MIME-Version

If this header is present it indicates that the email body is MIME formatted.

Eg. “MIME-Version: 1.0″

Content-Type

This header is used to specify the type of content sent in the email.

Eg. “Content-Type: text/plain”

Content-Disposition

The Content-Disposition was added to instruct the client to either:

  • Automatically display the MIME content “inline” when the message is displayed.
  • Require some form of user action to open the “attachment” MIME content.

In addition the Content-Disposition header also provides fields for specifying the name of the file, creation date and modification date.

Eg. “Content-Disposition:attachment; filename image1.png;”

Content-Transfer-Encoding

Indicates the encoding scheme that should be used by the receiving client to decode the MIME 7-bit ASCII content.

Eg. “Content-Transfer-Encoding: base64″

Multi-Part Messages

MIME Multi-Part messages allow the email body to be divided into multiple distinct parts.

Each MIME part has its own set of MIME Headers and is enclosed in the MIME boundary specified in the “Content-Type” header.

A MIME boundary is a string that must be unique and guaranteed not to occur in any of its MIME parts.

It is positioned before the first, after the last and in between each MIME part.

Attachments

There are essentially two main types of email attachments :-

  1. File attachments are standard attachments normally using “attachment” Content-Disposition.

    They appear as attachments that can be downloaded or viewed by the user.

    Each mime part representing file attachments should be nested inside a Multi-Part Mixed Structure.

  2. Embedded attachments on the other hand are slightly different in that these attachments are automatically displayed when the user views the email.

    Images for instance can be embedded within a HTML MIME part by referencing the attachment’s Content-ID in an image’s src attribute.

    Each mime part representing embedded attachments should be nested with a Multi-Part Related Structure and have Content-Disposition set to “inline”.

Example

Email containing multiple MIME parts :-

  • HTML version of the message.
  • Plain text version of the message.
  • 2 base64 encoded file attachments.
  • 2 base64 encoded inline attachments used to embed images in the email.

MIME Multi-Part Nesting Structure

MIME Multi-Part Nesting Structure

Email Source Code

From: from@qcode.co.uk
To: to@@qcode.co.uk
Subject: Example Email
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="MixedBoundaryString"

--MixedBoundaryString
Content-Type: multipart/related; boundary="RelatedBoundaryString"

--RelatedBoundaryString
Content-Type: multipart/alternative; boundary="AlternativeBoundaryString"

--AlternativeBoundaryString
Content-Type: text/plain;charset="utf-8"
Content-Transfer-Encoding: quoted-printable

This is the plain text part of the email.

--AlternativeBoundaryString
Content-Type: text/html;charset="utf-8"
Content-Transfer-Encoding: quoted-printable

<html>
  <body>=0D
    <img src=3D=22cid:masthead.png=40qcode.co.uk=22 width 800 height=3D80=
 =5C>=0D
    <p>This is the html part of the email.</p>=0D
    <img src=3D=22cid:logo.png=40qcode.co.uk=22 width 200 height=3D60 =5C=
>=0D
  </body>=0D
</html>=0D

--AlternativeBoundaryString--

--RelatedBoundaryString
Content-Type: image/jpgeg;name="logo.png"
Content-Transfer-Encoding: base64
Content-Disposition: inline;filename="logo.png"
Content-ID: <logo.png@qcode.co.uk>

amtsb2hiaXVvbHJueXZzNXQ2XHVmdGd5d2VoYmFmaGpremxidTh2b2hydHVqd255aHVpbnRyZnhu
dWkgb2l1b3NydGhpdXRvZ2hqdWlyb2h5dWd0aXJlaHN1aWhndXNpaHhidnVqZmtkeG5qaG5iZ3Vy
...
...
a25qbW9nNXRwbF0nemVycHpvemlnc3k5aDZqcm9wdHo7amlodDhpOTA4N3U5Nnkwb2tqMm9sd3An
LGZ2cDBbZWRzcm85eWo1Zmtsc2xrZ3g=

--RelatedBoundaryString
Content-Type: image/jpgeg;name="masthead.png"
Content-Transfer-Encoding: base64
Content-Disposition: inline;filename="masthead.png"
Content-ID: <masthead.png@qcode.co.uk>

aXR4ZGh5Yjd1OHk3MzQ4eXFndzhpYW9wO2tibHB6c2tqOTgwNXE0aW9qYWJ6aXBqOTBpcjl2MC1t
dGlmOTA0cW05dGkwbWk0OXQwYVttaXZvcnBhXGtsbGo7emt2c2pkZnI7Z2lwb2F1amdpNTh1NDlh
...
...
eXN6dWdoeXhiNzhuZzdnaHQ3eW9zemlqb2FqZWt0cmZ1eXZnamhka3JmdDg3aXV2dWd5aGVidXdz
dhyuhehe76YTGSFGA=

--RelatedBoundaryString--

--MixedBoundaryString
Content-Type: application/pdf;name="Invoice_1.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;filename="Invoice_1.pdf"

aGZqZGtsZ3poZHVpeWZoemd2dXNoamRibngganZodWpyYWRuIHVqO0hmSjtyRVVPIEZSO05SVURF
SEx1aWhudWpoZ3h1XGh1c2loZWRma25kamlsXHpodXZpZmhkcnVsaGpnZmtsaGVqZ2xod2plZmdq
...
...
a2psajY1ZWxqanNveHV5ZXJ3NTQzYXRnZnJhZXdhcmV0eXRia2xhanNueXVpNjRvNWllc3l1c2lw
dWg4NTA0

--MixedBoundaryString
Content-Type: application/pdf;name="SpecialOffer.pdf"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;filename="SpecialOffer.pdf"

aXBvY21odWl0dnI1dWk4OXdzNHU5NTgwcDN3YTt1OTQwc3U4NTk1dTg0dTV5OGlncHE1dW4zOTgw
cS0zNHU4NTk0eWI4OTcwdjg5MHE4cHV0O3BvYTt6dWI7dWlvenZ1em9pdW51dDlvdTg5YnE4N3Z3
...
...
OTViOHk5cDV3dTh5bnB3dWZ2OHQ5dTh2cHVpO2p2Ymd1eTg5MGg3ajY4bjZ2ODl1ZGlvcjQ1amts
dfnhgjdfihn=

--MixedBoundaryString--