Email for Users & Programmers (original) (raw)
Multipart Messages
The SectionMIME 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 atan 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 tothe 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, starts text that should be shown boldfaced; the same token with a slash, , 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 sobig! 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: andContent-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 apart-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 withaaaA. 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: ornmh-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 SectionCached Contents has more information.