14

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?

Hank
  • 4,597
  • 5
  • 42
  • 84
  • 3
    Not sure if it applies for upload, but you may also want to look at chunked encoding. – McDowell Sep 14 '11 at 21:55
  • 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 Sep 15 '11 at 04:21
  • 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 Jan 24 '20 at 19:39
  • @PatS you are joking, right? Why would a stream be held in memory? – Hank Jan 30 '20 at 07:54

2 Answers2

13

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());
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
10

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.

sixtyfootersdude
  • 25,859
  • 43
  • 145
  • 213
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 1
    Indeed, from the other side on, it's also perfectly valid to do a `response.setHeader("Content-Length", String.valueOf(someLong));`. You only need to be careful with 4GB limits on certain disk file systems and probably also the server's 2GB POST size config. – BalusC Sep 14 '11 at 21:58
  • 1
    @McDowell has a good point about "chuncked". (I think it's odd to process >2G files anyway..) – Bozho Sep 14 '11 at 22:00
  • @BalusC, could you please explain what you mean by *the server's 2GB POST size config*? thx. – Hank Sep 15 '11 at 07:10
  • @BalusC It isn't valid. `HttpURLConnection` sets this header automatically, unless you're using fixed-length or chunked transfer. – user207421 Feb 02 '16 at 08:40
  • 1
    FWIW, there is no reason to Capitalize. the header name. Header names are *defined* to be case-insensitive. – Christopher Schultz Mar 20 '19 at 15:15