Multipart

Why use multipart?

  • Multipart solves the problem of efficient file upload.
  • Before Multipart, the standard for uploading files was "application/x-www-form-urlencoded", which required clients to URL-encode the file before uploading it.
  • URL-encoding is efficient if the file is mostly ASCII text, but if it's mostly binary data, then you have to URL-escape almost every byte, which is very inefficient. (即纯文本的上传,用urlencoded效率也是挺高的
  • If you wanted to upload multiple files without encoding them, you could send multiple HTTP requests.
    • But that has more latency than sending them all in one request.
  • So in 1998, RFC 2388 proposed a new standard, "multipart/form-data", which lets you send many files in one HTTP body without encoding them.
    • No encoding means you save a lot of CPU cycles and keeps the total body size small.
    • You can use it to upload files from any HTTP client to any HTTP server. (not only in <form>)
    • The server can stream each part separately

What is multipart?

MIME types{Discreteone documentMultipart{message/multipart/\tt{MIME\ types} \begin{cases} \tt{Discrete} & \tt{one\ document} \\ \tt{Multipart} & \begin{cases} \tt message/ \\ \tt multipart/ \end{cases} \end{cases}
  • message/几乎不用
  • multipart/的实例:multipart/form-data

How is multipart implemented?

  • The HTTP body contains multiple parts
  • Each part is separated by a "boundary delimiter"
    • The root HTTP message has a header which defines the boundary delimiter
  • 其它header:
    • Content-Disposition : defines each part's filename or the name of the form field that contained it.
    • Content-Type: defines each part's MIME type.
      • It defaults to text/plain.
      • Unstructured binary data should use application/octet-stream
      • but if you know the type you should use it, e.g. application/zip, application/pdf, etc.
    • No other headers can be used!

RFC 7578: "The multipart/form-data media type does not support any MIME header fields in parts other than Content-Type, Content-Disposition, and (in limited circumstances) Content-Transfer-Encoding. Other header fields MUST NOT be included and MUST be ignored.".

a HTTP multipart body with 3 FIFs:

POST /cgi-bin/qtest HTTP/1.1
Content-Type: multipart/form-data; boundary=2a8ae6ad-f4ad-4d9a-a92c-6d217011fe0f
Content-Length: 514

--2a8ae6ad-f4ad-4d9a-a92c-6d217011fe0f
Content-Disposition: form-data; name="datafile1"; filename="r.gif"
Content-Type: image/gif

GIF87a.............,...........D..;
--2a8ae6ad-f4ad-4d9a-a92c-6d217011fe0f
Content-Disposition: form-data; name="datafile2"; filename="g.gif"
Content-Type: image/gif

GIF87a.............,...........D..;
--2a8ae6ad-f4ad-4d9a-a92c-6d217011fe0f
Content-Disposition: form-data; name="datafile3"; filename="b.gif"
Content-Type: image/gif

GIF87a.............,...........D..;
--2a8ae6ad-f4ad-4d9a-a92c-6d217011fe0f--

Compression

  • You can gzip the entire Multipart response(不能部分gzip)