Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP multipart/form-data multiple files in one <input>

Tags:

http

post

forms

The background:

According to W3c, multiple files selected in a <input> field, should be send by "multipart/mixed" type with separate boundary string and only one "name" parameter (as long, as the name should be unique in the form).

Writing POST data processing, I noticed that the major browsers send such multiple files as if they origins from different <input> elements, but with the same name. I.e. Instead of:

Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="files"
Content-Type: multipart/mixed; boundary=BbC04y

--BbC04y
Content-Disposition: file; filename="file1.txt"
Content-Type: text/plain

... contents of file1.txt ...
--BbC04y
Content-Disposition: file; filename="file2.gif"
Content-Type: image/gif

...contents of file2.gif...
--BbC04y--
--AaB03x--

...they send something like:

Content-Type: multipart/form-data; boundary=AaB03x

--AaB03x
Content-Disposition: form-data; name="files"; filename="file1.txt"
Content-Type: text/plain

... contents of file1.txt ...
--BbC04y
Content-Disposition: form-data; name="files"; filename="file2.gif"
Content-Type: image/gif

...contents of file2.gif...
--AaB03x--

The question:

How I should process the POST data? Are there browsers that will send multiple files as a "multipart/mixed" or handling such case is not needed and I should simplify my code?

Notice: I am writing framework for handling HTTP, so using other libraries and frameworks is not an option.

like image 243
johnfound Avatar asked Dec 18 '22 17:12

johnfound


1 Answers

I have confirmed what you found. I tested Firefox and Chromium, and this is what I get:

Content-Type: multipart/form-data; boundary=---------------------------148152952621447

-----------------------------148152952621447
Content-Disposition: form-data; name="files"; filename="fileOne.txt"
Content-Type: text/plain

this is fileOne.txt
-----------------------------148152952621447
Content-Disposition: form-data; name="files"; filename="fileTwo.txt"
Content-Type: text/plain

this is fileTwo.txt
-----------------------------148152952621447--

After an investigation, I found that the W3c information you provided is based on RFC2388, which is already made obsolete by RFC7578.

According to RFC7578 Section 4.3 (with my emphasis):

[RFC2388] suggested that multiple files for a single form field be transmitted using a nested "multipart/mixed" part. This usage is deprecated.

To match widely deployed implementations, multiple files MUST be sent by supplying each file in a separate part but all with the same "name" parameter.

So, your question:

How I should process the POST data?

My recommendation is ignore that W3c info and follow RFC7578.

Are there browsers that will send multiple files as a "multipart/mixed" or handling such case is not needed and I should simplify my code?

Very old browsers may use "multipart/mixed" but the usage is deprecated anyway, so no need to handle such case.

My recommendation: you should definitely simplify your code.

like image 183
Rei Avatar answered Dec 24 '22 01:12

Rei