Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the real file size of a file in a multipart/form-data request

As the title says, I need to get the real filesize of a file posted as a multipart/form-data request.

I'm based in the JSF world but I think the problem is technology-agnostic (only depends on HTTP).

The value specified in the Content-Length header is not sufficient because it includes the boundaries and other form parameters.

Example request (body only):

-----------------------------355432893771247592819421210
Content-Disposition: form-data; name="composeform"

composeform
-----------------------------355432893771247592819421210

Content-Disposition: form-data; name="javax.faces.ViewState"

-9107117821100047188:3613431652649065231
-----------------------------355432893771247592819421210
Content-Disposition: form-data; name="file"; filename="3byte.txt"
Content-Type: text/plain

abc

-----------------------------355432893771247592819421210--

The last part of the request body contains the file, in this case a file named "3byte.txt" containing the characters "abc".

As you can see, the filesize is not included in the request, therefore the only way I see to get the value, is to calculate it based on the Content-Length header and the size of the boundaries and other form parameters.

Additional requirements:

  • the solution shouldn't have to read/parse the whole request to get the filesize (this would obviously be easy)
  • there may be more form parameters in the request, before or/and after the part which contains the file (in contrast to my example)

Similar questions not solving the problem:

  • How to know the file size when uploading via multipart form-data?
  • Get file size from multipart form upload Content-Length header
  • Calculate size multipart/form-data encoded file
like image 803
unwichtich Avatar asked Dec 09 '15 16:12

unwichtich


1 Answers

  1. You cannot expect that the Content-Length header is set for the multipart message (some multipart request types even forbid a content length header). It's only required that either a Content-Length header or a Transfer-Encoding header is present.

  2. There must be no Content-Length header in a part of a multipart message.

However, your sender may set an additional parameter in the disposition header. You could leverage this to set the file size as follows:

Content-Disposition: form-data; name="file"; filename="3byte.txt"; size=123

But this would be purely optional, the parameters's name would be arbitrary, and no sender is required to include this parameter. That means, a HTTP server engine can never rely on it.

like image 156
CouchDeveloper Avatar answered Sep 29 '22 08:09

CouchDeveloper