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:
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 aContent-Length
header or aTransfer-Encoding
header is present.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:
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.