Question

What happen if I do not specify the Content-Length header when I send a HttpServletResponse containing a zip file?

I did some tests and it seems that the header is set by default with the correct file length. Can I be sure that this always happens. When I can found some documentation about?

Was it helpful?

Solution

If the actual response content length fits entirely in the response buffer, which is usually 2KB (it depends on server make/version/config), then the content length header will be set. However, if the actual response content length is larger than the response buffer, so that it would be flushed sooner than the end of response content is reached, then the servlet will send the response with chunked encoding and ignore any attempts to set the content length header.

This is mentioned in among others the javadoc of HttpServlet#doGet() which is cited below:

...

Where possible, set the Content-Length header (with the ServletResponse.setContentLength(int) method), to allow the servlet container to use a persistent connection to return its response to the client, improving performance. The content length is automatically set if the entire response fits inside the response buffer.

When using HTTP 1.1 chunked encoding (which means that the response has a Transfer-Encoding header), do not set the Content-Length header.

...

With "normal" encoding, the data is sent as one continuous block.

actualContent

With chunked encoding, the data is sent in chunks which look like this

part1LengthInHexadecimal
actualPart1Content

part2LengthInHexadecimal
actualPart2Content

part3LengthInHexadecimal
actualPart3Content

0

The part length in hexadecimal indicates the client how large the next chunk of data is (so that it won't "accidently" parse the next chunk as part of current chunk). Finally, the client glues the parts together. This is by the way also the default behavior when Gzip is used on the response, for the obvious reason that the final content length is unknown beforehand.

See also the example in wikipedia.

Note that when omitting the content length on a file download, then the user experience will be that the file download progress is unknown. I.e. the enduser won't see any indication of the file size and remaining bytes/time. If this user experience is important to you, then you should really set the content length beforehand. You can do this by first writing to an in-memory buffer (e.g. new ByteArrayOuputStream(bytes) or a temporary file (e.g. Files#createTempFile(), so you can get the content length by bytes.length or file.length(), and then finally write that temporary buffer/file to the response.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top