# Multipart Messages

The Section MIME Header Fields introduced six content types: text, image, audio, video, message, and multipart. A multipart message is different from the other five. A multipart message has more than one part. Each part can have its own content type.

## A Sample Multipart Message

Let's start by looking at an Example, a fairly simple multipart message. This shows the MIME message as it's sent to the recipient. Luckily, you don't have to enter all this stuff to send a multipart message! A lot of it is added automatically. But going through it will help you understand what MH is doing and how the message is structured. (If you want to look ahead to the next Example, you'll see how the decoded message might look.)

Example: Sample multipart message, encoded

        From: Laura Rios <laura@oara.sf.ca.us>
        To: steve@ntecom.za
        Subject: Sara is two!
        Mime-Version: 1.0
        Content-Type: multipart/mixed; boundary="Snip snip snip"

Prologue: any text here is ignored by MIME mail programs

        --Snip snip snip
        Content-Type: text/enriched; charset="us-ascii"

        Hi, Steve.  Sara had her second birthday yesterday.  Can you believe it?
        She is so <bold>big</bold>!  Now if we can just live through the
        "terrible twos" for a year, <italic>sigh</italic>.

        Here are a few words from her.  I've also scanned in a picture of her
        party.  Tell your boss thanks for letting us keep in touch by email.

        Laura

        --Snip snip snip
        Content-type: audio/basic
        Content-transfer-encoding: base64
        Content-description: Sara says "I love you, Steve" (awww)

        /Xr++/hoX2lqeXt8d/7z8/D5+PLw7/b+9fD09319/vz5f3j//Pz9fHp7fvrs9Wz/eH59d

omitted...

        /////////////////y8=

        --Snip snip snip
        Content-type: image/gif
        Content-transfer-encoding: base64
        Content-description: Cutting the cake, sort of

        R0lGODdhQAHIAKMAAAAAAP+2bQAAACQAAAAASEgAAAAkSEgkJG0kJJEkAABIkZFIJCRttrZt

omitted...

        l7Vry4B9aM+yKjifMosAADs=

        --Snip snip snip--

Epilogue: any text here is ignored by MIME mail programs

The sample message (above) has three parts. The parts are separated by a boundary, which is specified as a parameter in the main `Content-type:` header field. Each part boundary starts with two dashes (`--` ). The last boundary in a message also ends with two dashes. It's important to pick a boundary that won't appear anywhere in the parts. MH chooses unique (but ugly) boundaries automatically; in this example, I used "`Snip snip snip`."

You can put text (the preamble) before the first boundary and more text (epilogue) after the last boundary. MIME mail readers will ignore the preamble and the epilogue, but non-MIME programs show it. So the preamble is a good place to put explanation for people who don't have MIME readers.

Each part of the message has its own header fields, called body part header fields. A plain text ASCII part doesn't need a `Content-type:` field.

Usually, but not always, the first part of a multipart message is text that introduces or explains the rest of the message. You can also sprinkle text parts throughout the message -- to explain the following non-text parts, for instance. A part can also have a `Content-description:` header field that summarizes what's in that part.

The first part of this sample message has a text/enriched content-type. Enriched text gives you some of the features of a word processor -- like boldface and italic text -- in a plain-ASCII message. For instance, `<bold>` starts text that should be shown boldfaced; the same token with a slash, `</bold>`, ends the boldfacing. The recipient's mail program justifies the text to fit the display; they may not be formatted the way you type them.

Line and paragraph breaks are handled in a clever way. To break a line of text at a particular place, leave an empty line. To end a paragraph, leave two empty lines. The enriched text reader will "eat" single empty lines to give the formatted effect you want; people with non-MIME mail programs will see the extra blank lines but should still get the idea.

The next Example shows what would happen as Steve's MH setup displays that message. (What would happen on your MH system depends on your setup. See the Chapter Making MH Work Your Way.)

Example: Sample multipart message, decoded

        % show
        (Message inbox:34)
        From: Laura Rios <laura@oara.sf.ca.us>
        To: steve@ntecom.za
        Subject: Sara is two!
        (END)

        Part 1    text/plain     356
        Press <return> to show content...

Hi, Steve. Sara had her second birthday yesterday. Can you believe it? She is so big! Now if we can just live through the "terrible twos" for a year, sigh.

Here are a few words from her. I've also scanned in a picture of her party. Tell your boss thanks for letting us keep in touch by email.

Laura

        Part 2    audio/basic     7200 Sara says "I love you, Steve" (awww)
        Press <return> to show content...

        ...sound plays on Steve's workstation speaker...

        Part 3    image/gif    57600 Cutting the cake, sort of
        Press <return> to show content...

        ...Window with color picture pops up...

        %

## Multipart/alternative Messages

Another important kind of multipart message is multipart/alternative. It presents the same information in two or more ways, and the recipient's MUA chooses the most faithful form it can process. So, unlike other multipart message subtypes (where all parts are displayed), only one part of a multipart/alternative message is shown.

For instance, a multipart/alternative message might contain the same words in plain text, enriched text, and PostScript formats. If the recipient's MUA can display PostScript (with its assorted fonts, figures, and so on), the MUA will show that part; otherwise it will display enriched or plain text. When you compose a multipart/alternative message, the simplest format (the one closest to plain text) must come first. This rule makes it easier for someone with a non-MIME MUA to find the plain text.

Here's an example:

        From: Jerry Peek <jerry@ora.com>
        To: mh-users@ics.uci.edu
        Subject: New edition of "MH & xmh" covers MIME and MH-E
        MIME-Version: 1.0
        Content-Type: multipart/alternative; boundary="----- =_aaaaaaaaaa0"
        Content-ID: <1283.780402430.1@ora.com>

        ------- =_aaaaaaaaaa0
        Content-Type: text/plain; charset="us-ascii"
        Content-ID: <1283.780402430.2@ora.com>

        We've just released the new third edition of "MH & xmh: Email for
        Users & Programmers."  Changes include:
            - MIME (Multimedia) mail
            - The popular MH-E GNU Emacs front-end to MH
                ...omitted...

        ------- =_aaaaaaaaaa0
        Content-Type: text/enriched; charset="us-ascii"
        Content-ID: <1283.780402430.3@ora.com>

        We've just released the new third edition of <italic>MH & xmh: Email
        for Users & Programmers</italic>. Changes include:

        <indent>
        - MIME (Multimedia) mail

        - The popular MH-E GNU Emacs front-end to MH
                ...omitted...

        ------- =_aaaaaaaaaa0
        Content-Type: application/postscript
        Content-ID: <1283.780402430.4@ora.com>
        Content-Transfer-Encoding: quoted-printable

        %!PS-Adobe-3.0
        %%Creator: groff version 1.09
                ...omitted...
        %%Trailer
        end
        %%EOF

        ------- =_aaaaaaaaaa0--

MH automatically created the boundaries. It added the first `Content-Type:` and all `Content-ID:` and `Content-Transfer-Encoding:` fields. This is the file I gave to MH to create the MIME message:

        From: Jerry Peek <jerry@ora.com>
        To: mh-users@ics.uci.edu
        Subject: New edition of "MH & xmh" covers MIME, exmh, and MH-E
        --------
        #begin alternative
        We've just released the new third edition of "MH & xmh: Email for
                ...omitted...
        #<text/enriched
        We've just released the new third edition of <italic>MH & xmh: Email
                ...omitted...
        #application/postscript /u/jerry/mh-book/3rd_edition.ps
        #end

To find out more about MIME message composition, read the introduction in Section Sending MIME Mail and the details in Section Composing and Sending MIME Messages.

## Parts within Parts

Multipart MIME messages can have a hierarchical structure like trees or outlines or UNIX directories: each part can be made of more parts. When MH shows these messages, it will work through the parts from first to last. The command mhn -list (for MH) or mhlist (for nmh-1.0 and above) shows a message structure and assigns numbers to the parts. (mhn is the MH command that processes MIME. There's much more about mhn and the corresponding nmh commands later in this book.)

The first part of the example message below is an overview. Next are two comments from the company's President Parker -- about jobs and the budget. Here's the mhn listing of message number 91:

        % mhn -list 91
         msg part  type/subtype              size description
          91       multipart/mixed           272K
             1     text/plain                2168 Overview of this message
             2     multipart/alternative     113K
             2.1   audio/basic               110K Parker re: jobs (audio)
             2.2   text/plain                 937 Parker re: jobs (transcript)
             3     multipart/alternative     159K
             3.1   audio/basic               156K Parker re: budget (audio)
             3.2   text/plain                1029 Parker re: budget (transcript)

As explained above, part 1 is an overview (the description of the part comes from the `Content-Description:` field). Part 2 and Part 3 are each two separate multipart/alternative messages; each part has the same information, first as audio and then as text. The first subpart of each part (2.1 and 3.1) are audio versions; they'll be played if your MH setup can play sound. Otherwise, parts 2.2 and 3.2 will be displayed; they have plain-text versions of the audio parts. (Note that mhn -list and mhlist don't necessarily show the parts in the same order as the original message.)

You don't have to read all of a message; you can specify the parts you want to see with a part-showing command like mhn -part 3.2 (MH) or mhshow -part 3.2 (nmh-1.0+).

Making subparts is simple if you remember that each part should be able to stand on its own. A part that's divided into subparts needs its own boundary marker. You don't have to worry about the boundary markers, though; MH will choose the right ones. Here's a look at the multipart message number 91 from the example above:

        From: Clipping Service <audio@xxx.com>
        To: managers@xxx.com
        Subject: Parker on jobs and budget, 23 August 1994
        MIME-Version: 1.0
        Content-Type: multipart/mixed; boundary="----- =_aaaaaaaaaaA"
        Content-ID: <1458.780409280.0@xxx.com>

        ------- =_aaaaaaaaaaA
        Content-Type: text/plain; charset="us-ascii"

        Content-Description: Overview of this message

        This message has two sections of plain text and audio.  If your
        mail reader can play audio, you'll hear those parts; otherwise you'll
        see the plain-text transcripts.
                ...omitted...

        ------- =_aaaaaaaaaaA
        Content-Type: multipart/alternative; boundary="----- =_aaaaaaaaaaB"

        ------- =_aaaaaaaaaaB
        Content-Type: text/plain; charset="us-ascii"

        Content-Description: Parker re: jobs (transcript)
                ...omitted...

        ------- =_aaaaaaaaaaB
        Content-Type: audio/basic

        Content-Description: Parker re: jobs (audio)
                ...omitted...

        ------- =_aaaaaaaaaaB--

        ------- =_aaaaaaaaaaA
        Content-Type: multipart/alternative; boundary="----- =_aaaaaaaaaaC"

        ------- =_aaaaaaaaaaC
        Content-Type: text/plain; charset="us-ascii"

        Content-Description: Parker re: budget (transcript)
                ...omitted...

        ------- =_aaaaaaaaaaC
        Content-Type: audio/basic

        Content-Description: Parker re: budget (audio)

                ...omitted...

        ------- =_aaaaaaaaaaC--

        ------- =_aaaaaaaaaaA--

If you compare the boundaries to the mhn -list output above, you'll see how the parts and subparts are structured. The main parts (1, 2, and 3) are separated by a boundary that ends with `aaaA`. Parts 2 and 3, which have their own subparts, use subpart boundaries that end with `aaaB` and `aaaC`, respectively. These automatically generated boundaries also contain the string `=_`, which is guaranteed not to appear in any possible quoted-printable or base64 encodings.

That message was almost 300K bytes long. Sending it to 200 people around the company could use a big chunk of network capacity. MIME and MH have two ways to help with the problem of long message parts:

- External body parts aren't transmitted with the message. Instead, the MIME-capable program will ask the recipients whether they would like to retrieve the body part. If the answer is "yes," the mail program will fetch that part over the network. This method cuts the size of recipients' mailboxes and helps them control the cost of their incoming email by letting them select message parts. The Section External Parts shows how to read mail with external parts; The Section Example Drafts with Directives and Table 3 in Section Syntax of MIME Draft Directives help you send those messages.

  Of course, this won't work everywhere. Not everyone is directly connected to a network, and network "firewalls" can keep recipients from retrieving files over their connections. The `mhn-access-ftp:` or `nmh-access-ftp:` profile entry is for getting network access by other methods.

- Cached body parts are stored in a local file by MH. They're useful for messages that several people on the same computer will be receiving. If MH is set up to save messages in a shared cache (storage area), the first person on a host who retrieves a body part can store it in the cache. Later, other people on the same system can use the cached part automatically instead of re-transmitting that part over the network. The Section Cached Contents has more information.