JDK-8218662 : Allow 204 responses with Content-Length:0
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 11.0.2,12
  • Priority: P1
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2019-02-08
  • Updated: 2020-02-14
  • Resolved: 2019-02-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 12 JDK 13
11.0.7-oracleFixed 12 b32Fixed 13Fixed
Related Reports
Blocks :  
Duplicate :  
Relates :  
Relates :  
Description
Seems like a regression of JDK-8211437.

cURL works fine with the same URI.

$ curl http://clients1.google.com/generate_204 -v
*   Trying 74.125.193.101...
* TCP_NODELAY set
* Connected to clients1.google.com (74.125.193.101) port 80 (#0)
> GET /generate_204 HTTP/1.1
> Host: clients1.google.com
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 204 No Content
< Content-Length: 0
< Date: Fri, 08 Feb 2019 10:00:15 GMT
< 
* Connection #0 to host clients1.google.com left intact

Comments
Fix Request (11u) This resolves critical regression since 11.0.2. Patch applies cleanly to 11u, new test fails without the product patch, passes with it. Patched JDK passes tier{1,2,3} on Linux x86_64.
12-02-2020

Verified on jdk-12+32 build, regression test and attached samples all passed. As comparison, on previous b31 build got "unexpected content length header with 204 response"
15-02-2019

This is the exception when running attached test case FooBar. (Hadn't seen the test case provided by submitter). Exception in thread "main" java.io.IOException: unexpected content length header with 204 response at java.net.http/jdk.internal.net.http.HttpClientImpl.send(HttpClientImpl.java:576) at java.net.http/jdk.internal.net.http.HttpClientFacade.send(HttpClientFacade.java:119) at com.foo.FooBar.main(FooBar.java:18) Caused by: java.io.IOException: unexpected content length header with 204 response at java.net.http/jdk.internal.net.http.MultiExchange.lambda$responseAsync0$4(MultiExchange.java:298) at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1146) at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506) at java.base/java.util.concurrent.CompletableFuture.postFire(CompletableFuture.java:610) at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:649) at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:478) at java.net.http/jdk.internal.net.http.HttpClientImpl$DelegatingExecutor.execute(HttpClientImpl.java:155) at java.base/java.util.concurrent.CompletableFuture$UniCompletion.claim(CompletableFuture.java:568) at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:638) at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506) at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2144) at java.net.http/jdk.internal.net.http.Http1Response$HeadersReader.handle(Http1Response.java:686) at java.net.http/jdk.internal.net.http.Http1Response$HeadersReader.handle(Http1Response.java:612) at java.net.http/jdk.internal.net.http.Http1Response$Receiver.accept(Http1Response.java:603) at java.net.http/jdk.internal.net.http.Http1Response$HeadersReader.tryAsyncReceive(Http1Response.java:659) at java.net.http/jdk.internal.net.http.Http1AsyncReceiver.flush(Http1AsyncReceiver.java:233) at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SynchronizedRestartableTask.run(SequentialScheduler.java:175) at java.net.http/jdk.internal.net.http.common.SequentialScheduler$CompleteRestartableTask.run(SequentialScheduler.java:147) at java.net.http/jdk.internal.net.http.common.SequentialScheduler$SchedulableTask.run(SequentialScheduler.java:198) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at java.base/java.lang.Thread.run(Thread.java:835) Process finished with exit code 1
08-02-2019

RFC 2616 does not explicitly disallow this behavior. So, it seems prudent to allow it despite what RFC 7230 says. Content-length value of 0 should be allowable, but any other value will cause an exception
08-02-2019

Strictly not a bug since the server is sending a Content-length header in the response contrary to RFC 7230: "A server MUST NOT send a Content-Length header field in any response with a status code of 1xx (Informational) or 204 (No Content). " It's also not a regression since the fix is working as intended. That said, perhaps we should be more permissive about it considering other clients appear to accept it without an error.
08-02-2019

Fix request approved This is important functionality which appears to have regressed and the fix is low risk.
08-02-2019

Fix Request It is important to fix this bug because: 1) it impacts interoperability with some popular servers, and 2) it could be perceived as a regression in behaviour from the previous release, JDK 11. The fix updates the specific code for handling 204 response codes only. Rather than disallowing any Content-Length header from being present, the fix will allow the header to be present only when it has a value of zero. The risk is considered very low since the code changes are small, localized, and well understood. All HTTP Client, Networking, and tier1-tier2-tier3 tests have been run successfully. The fix has been reviewed by @michaelm. RFR https://mail.openjdk.java.net/pipermail/net-dev/2019-February/012180.html Webrev https://cr.openjdk.java.net/~chegar/8218662/webrev.00/
08-02-2019