RFC 2388

Returning Values from Forms: multipart/form-data

πŸ“… published August 1998, from ietf

RFC 2388: Returning Values from Forms: multipart/form-data πŸ’–

πŸ“œ The title block, in a nutshell: this is RFC 2388, written by Larry Masinter at Xerox Corporation 🧚 in August 1998. It's a Standards Track document πŸŽ€. The header doesn't list anything it obsoletes or updates, so it stands on its own ✨.

Status of this Memo πŸ“Œ

This document specifies an Internet standards track protocol for the Internet community, and requests discussion and suggestions for improvements. Please refer to the current edition of the "Internet Official Protocol Standards" (STD 1) for the standardization state and status of this protocol. Distribution of this memo is unlimited.

Copyright (C) The Internet Society (1998). All Rights Reserved.

1. Abstract 🌸

Okay so this spec defines a brand-new Internet Media Type called multipart/form-data πŸ¦‹. It's giving "versatile," because tons of different apps can use it and tons of different protocols can carry it. Its whole job is returning a bunch of values after a user fills out a form πŸ’….

2. Introduction πŸ“

Picture this: a user gets shown a form. They fill it out by typing stuff, by picking things that get generated from their input, or by attaching files they selected. Once the form is done, that data gets sent from the user over to the receiving application πŸ’–.

The multipart/form-data format comes from one of those apps, first described in [RFC1867] and later folded into [HTML40], where forms are written in HTML and the form values travel over HTTP or email. It's super widely implemented in web browsers and web servers, so it's already a big deal πŸ”₯.

BUT here's the twist ✨: multipart/form-data can also be used for forms that aren't HTML (think spreadsheets, Portable Document Format, and so on), and it can travel by means other than email or HTTP. So this document defines how form values are represented without tying them to any one application 🧚.

3. Definition of multipart/form-data πŸŽ€

The media type multipart/form-data follows the rules of all multipart MIME data streams as outlined in [RFC 2046]. In a form, there's a series of fields that the user fills in. Every field has a name, and within a single form, those names are unique πŸ’œ.

"multipart/form-data" holds a series of parts. Each part is expected to contain a content-disposition header [RFC 2183] where the disposition type is "form-data". The disposition also carries an (additional) parameter called "name", and its value is the original field name from the form. For example, a part might contain this header:

Content-Disposition: form-data; name="user"

and then the value that matches whatever the user typed into the "user" field 🌈.

Field names that were originally in non-ASCII character sets can be encoded inside the value of the "name" parameter, using the standard method from RFC 2047 πŸ¦‹.

Just like every other multipart MIME type, each part has an optional "Content-Type", and it defaults to text/plain πŸ’…. If a file's contents come back through a form, the file input gets labelled with the right media type if it's known. If it isn't known, it gets "application/octet-stream" πŸ™ˆ. And if several files come back as the result of one single form entry, they should be represented as a "multipart/mixed" part nested inside the "multipart/form-data" πŸ“.

Each part may be encoded, and if its value doesn't match the default encoding, the "content-transfer-encoding" header gets supplied to say so 🫢.

4. Use of multipart/form-data πŸ’…

4.1 Boundary πŸŽ€

Just like with other multipart types, the boundary gets picked so that it never shows up in any of the data πŸ›‘οΈ. Every field in the form gets sent as a part of the multipart stream, in the order the sending application and form define 🧚. Each part identifies the INPUT name from the original form. Each part should be labelled with an appropriate content-type if the media type is known (for example, inferred from the file extension or from the operating system's file typing info). If it isn't known, the label is "application/octet-stream" πŸ’–.

4.2 Sets of files πŸ“

If a form field's value is a set of files instead of just one file, that whole value can be transferred together using the "multipart/mixed" format 🌸.

4.3 Encoding 🌈

The HTTP protocol can carry arbitrary binary data, but for mail transport the default is the 7BIT encoding ✨. A part's value might need encoding, and then the content-transfer-encoding header has to be supplied if the value doesn't match the default encoding. [See section 5 of RFC 2046 for more details.] 🫢

4.4 Other attributes πŸ¦‹

Forms can ask the user for file inputs, and the form software can include the file name along with other file attributes, as specified in [RFC 2184] πŸ“Ž.

The original local file name can also be supplied. It can go in as a "filename" parameter on the content-disposition: form-data header, or, when there are multiple files, in a content-disposition: file header on the subpart 🧚. The sending application MAY supply a file name. If the sender's operating system file name isn't in US-ASCII, the file name might be approximated, or encoded using the method of RFC 2231 πŸ”₯.

This is handy for cases where the files a form sends might point at each other. A good example is a TeX file and its .sty auxiliary style description πŸ’œ.

4.5 Charset of text in form data πŸ’¬

Each part of a multipart/form-data is supposed to have a content-type. When a field element is text, the charset parameter tells you which character encoding got used 🌈.

Here's an example. Say a text field has a user who typed 'Joe owes <eu>100', where <eu> is the Euro symbol. The form data might come back looking like this:

--AaB03x
content-disposition: form-data; name="field1"
content-type: text/plain;charset=windows-1250
content-transfer-encoding: quoted-printable

Joe owes =80100.
--AaB03x

5. Operability considerations πŸ› οΈ

5.1 Compression, encryption πŸ”

Some of the data in forms might be compressed or encrypted, using other MIME mechanisms. That's up to the application generating the form data πŸ’….

5.2 Other data encodings rather than multipart 🧩

People have floated the idea of a brand-new top-level MIME type called "aggregate" (like aggregate/mixed), or a content-transfer-encoding called "packet", to express indeterminate-length binary data. That'd skip the multipart-style boundaries. Honestly it would be useful, BUT the "multipart" mechanisms are already well established, simple to implement on both the sending client and the receiving server, and just as efficient as other ways of handling several combos of binary data πŸ’–.

multipart/form-data does have high overhead and a performance hit when there are lots of fields with short values. In practice though, for the forms in use (HTML forms, for example), the average overhead isn't significant 🌸.

5.3 Remote files with third-party transfer 🌍

Sometimes the user filling out the form might want to point at a URL for remote data instead of a local file. Is there a way to let the browser send the client a pointer to the external data, instead of the entire contents? One option would be having the client send the server data of type "message/external-body" with "access-type" set to, say, "uri", with the URL of the remote data in the body of the message πŸ¦‹.

5.4 Non-ASCII field names πŸ”€

MIME headers are generally required to be 7-bit data in the US-ASCII character set. So if field names have characters outside that set, they should be encoded using the method in RFC 2047 πŸŽ€.

5.5 Ordered fields and duplicated field names πŸ”

This spec doesn't define how the order of fields in a form relates to the order of the returned values in multipart/form-data. It doesn't define what happens when a form has multiple fields with the same name either πŸ™ˆ. HTML-based forms may send results back in the order they were received, and intermediaries should not reorder the results. But some systems might not define a natural order for form fields at all πŸ’….

5.6 Interoperability with web applications 🌐

Lots of web apps use the "application/x-url-encoded" method to return form data. It's super compact, for example:

name=Xavier+Xantico&verdict=Yes&colour=Blue&happy=sad&Utf%F6r=Send

BUT there's no way to label the enclosed data with a content type, apply a charset, or use other encoding mechanisms 😭.

Many form-interpreting programs (mostly web browsers) now implement and generate multipart/form-data. Still, an existing application might need to optionally support application/x-url-encoded as well 🧚.

5.7 Correlating form data with the original form πŸ”—

This spec gives no specific mechanism for linking multipart/form-data back to the form that sent it. That separation is on purpose, since many different forms might be used to transmit the same data πŸ’œ. In practice, applications may supply a specific form processing resource for each different form (in HTML, that's the ACTION attribute in a FORM tag) 🌈. Another option is putting data about the form into a "hidden field", which is a field that's part of the form but has a fixed value to be sent back to the form-data processor ✨.

Appendix A. Media type registration for multipart/form-data ✨

okay bestie, this is the registration template for multipart/form-data πŸ“‹ and it's shorter than you'd think πŸ’…

   Media Type name:
     multipart

   Media subtype name:
     form-data

   Required parameters:
     none

   Optional parameters:
     none

   Encoding considerations:
     No additional considerations other than as for other multipart
     types.

   Security Considerations
     Applications which receive forms and process them must be careful
     not to supply data back to the requesting form processing site that
     was not intended to be sent by the recipient. This is a
     consideration for any application that generates a multipart/form-
     data.

     The multipart/form-data type introduces no new security
     considerations for recipients beyond what might occur with any of
     the enclosed parts.

So the media type is multipart, the subtype is form-data πŸŽ€, and it has no required parameters and no optional parameters πŸ¦‹. For encoding, it's literally just the same as every other multipart type. Nothing extra, no drama 🌸

Security Considerations

okay, this part is serious, so pay attention 🫢 Any app that receives forms and then processes them has to be super careful. You must not send data back to the form-processing site that the person receiving the form never meant to send 😭 And this isn't only for receiving apps. It applies to any app that generates a multipart/form-data body too πŸ’€

The good news is that the type itself doesn't add any new security problems for recipients. Whatever risks show up are the same ones you'd get from any of the parts that are inside the message 🌈 So the real question is what's in each part, not the wrapper πŸ‘‘

References

Here's the full reading list, no skipping πŸ“šβœ¨

   [RFC 2046] Freed, N., and N. Borenstein, "Multipurpose Internet Mail
              Extensions (MIME) Part Two: Media Types", RFC 2046,
              November 1996.

   [RFC 2047] Moore, K., "MIME (Multipurpose Internet Mail Extensions)
              Part Three: Message Header Extensions for Non-ASCII Text",
              RFC 2047, November 1996.

   [RFC 2231] Freed, N., and K. Moore, "MIME Parameter Value and Encoded
              Word Extensions: Character Sets, Languages, and
              Continuations", RFC 2231, November 1997.

   [RFC 1806] Troost, R., and S. Dorner, "Communicating Presentation
              Information in Internet Messages: The Content-Disposition
              Header", RFC 1806, June 1995.

   [RFC 1867] Nebel, E., and L. Masinter, "Form-based File Upload in
              HTML", RFC 1867, November 1995.

   [RFC 2183] Troost, R., Dorner, S., and K. Moore, "Communicating
              Presentation Information in Internet Messages: The
              Content-Disposition Header Field", RFC 2183, August 1997.

   [RFC 2184] Freed, N., and K. Moore, "MIME Parameter Value and Encoded
              Word Extensions: Character Sets, Languages, and
              Continuations", RFC 2184, August 1997.

   [HTML40]   D. Raggett, A. Le Hors, I. Jacobs. "HTML 4.0
              Specification", World Wide Web Consortium Technical Report
              "REC-html40", December, 1997. <http://www.w3.org/TR/REC-
              html40/>

Here's the legal stuff, kept exactly as it's written πŸ¦‹βš–οΈ

   Copyright (C) The Internet Society (1998).  All Rights Reserved.

   This document and translations of it may be copied and furnished to
   others, and derivative works that comment on or otherwise explain it
   or assist in its implementation may be prepared, copied, published
   and distributed, in whole or in part, without restriction of any
   kind, provided that the above copyright notice and this paragraph are
   included on all such copies and derivative works.  However, this
   document itself may not be modified in any way, such as by removing
   the copyright notice or references to the Internet Society or other
   Internet organizations, except as needed for the purpose of
   developing Internet standards in which case the procedures for
   copyrights defined in the Internet Standards process must be
   followed, or as required to translate it into languages other than
   English.

   The limited permissions granted above are perpetual and will not be
   revoked by the Internet Society or its successors or assigns.

   This document and the information contained herein is provided on an
   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
πŸ“¦ where this page comes from