Messages and MIME
Multipart messages and attachments
Use MIME boundaries to carry alternative bodies, related resources, and file attachments.
8 minute lesson
A multipart body contains several parts separated by a boundary declared in its Content-Type field. Each part has its own MIME headers and body.
multipart/alternative offers representations of the same content, commonly plain text followed by HTML. multipart/mixed groups independent parts, commonly a message body and attachments.
Content-Disposition: attachment suggests that a part should be presented as a downloadable file. A filename is presentation metadata, not proof that the bytes are safe. Applications must still validate and scan attachments.
A minimal multipart message looks like this:
Content-Type: multipart/mixed; boundary="mail-boundary-42"
--mail-boundary-42
Content-Type: text/plain; charset=utf-8
The report is attached.
--mail-boundary-42
Content-Type: application/pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="report.pdf"
JVBERi0xLjQK
--mail-boundary-42--
The closing delimiter has two extra hyphens. The boundary value must not occur inside a part. Real MIME structures can nest: multipart/alternative for text and HTML can sit inside multipart/mixed beside attachments.
Clients usually prefer the last representation they understand in multipart/alternative, but every representation should express the same message. Do not put tracking or essential content only in the HTML part.
Sanitize filenames before writing them. Remove path components, choose your own storage name, limit decoded size, and scan the decoded bytes. A filename such as ../../report.pdf must never control a filesystem path.
Extend the example with a nested plain-text and HTML alternative. Draw the MIME tree before writing the boundaries.
Lesson completed