Trust the Content-Length header

When you’re implementing a file upload you most probably want to limit the size of the upload. But how do you know the size? Reading the Content-Length header should be obvious but can you really trust it?
No, the client can send whatever he wants, correct?
There are a lot of creative ways to be really sure for instance (using JAX-RS and Commons IO):

byte[] data = IOUtils.toByteArray(inputStream);
if (data.length > MAX_UPLOAD_SIZE) {
return Response.status(413).build();

Don’t do this. You’re loading the whole stream into your servers memory. The memory of your server is limited. It will crash if there’s no memory left. So by trying to validate the upload size you are providing something like a power off button to your users.

The solution is easier. Trust the Content-Length header and validate if the size is ok. The rest should be handled by your server. It will simply stop reading when the Content-Length header size is reached.

You don’t know if your server or application framework really handles this for you? Implement a resource which returns the uploaded data and do a simple test:

$ curl -X POST \
-F 'file=foobar' \
-H 'Content-Length: 90' \
$ foo

This will do a multipart/form-data upload with a part named ‘file’ with ‘foobar’ as content. The response should be ‘foo’ without ‘bar’ but why am I using a Content-Length of 90 instead of 3(the length of ‘foo’)? A multipart/form-data request can contain multiple parts separated by a boundary so the request body is a bit longer:

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

Keep in mind that the Content-Length header covers the whole request data of multiple files.



developer at

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store