13
votes

In order to deal with a large request body in a HTTP POST or PUT, relying on HttpServletRequest.getContentLength() is not a good idea, since it returns only integer values, or -1 for request bodies > 2GB.

However, I see no reason, why larger request bodies should not be allowed. RFC 2616 says

Any Content-Length greater than or equal to zero is a valid value.

Is it valid to use HttpServletRequest.getHeader('content-length') and parse it to Long instead?

2
Not sure if it applies for upload, but you may also want to look at chunked encoding. - McDowell
Java Servlet came out in 1997; 2GB was quite unthinkable at the time. was there even 1GB consumer harddisks back then? RFC 2616 is dated 1999. - irreputable
From a communications and systems perspective, developing APIs that require 2G or more are problematic when it comes to practical application. Imagine that 4G were supported, and you had just 20 users, you would need 80G of ram just to handle the initial copy of this data. Some applications make copies of some or all of the payload data to put it into an application data structure so now the 80G becomes 120G to 160G and that is just for 20 users. The question is a valid but IMO the spec being "int" is sufficient for all but the most high speed applications which are not likely using HTTP. - PatS
@PatS you are joking, right? Why would a stream be held in memory? - Hank

2 Answers

10
votes

Yes, this is a fine approach - use getHeader("Content-Length") (capitalized) and Long.parseLong(..). I believe it's what the container is doing, but it is limited to int by the serlvet spec.

10
votes

Since Servlet 3.1 (Java EE 7), a new method is available, getContentLengthLong():

long contentLength = request.getContentLengthLong();

The same applies to its counterpart on the response, setContentLengthLong():

response.setContentLengthLong(file.length());