JDK-8211420 : com.sun.net.httpserver.HttpServer returns Content-length header for 204 response code
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 8,11,12
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2018-10-01
  • Updated: 2018-11-21
  • Resolved: 2018-10-05
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
11.0.2Fixed 12 b15Fixed
Related Reports
Relates :  
Relates :  
Description
A DESCRIPTION OF THE PROBLEM :
This violates RFC7230:
- "A server MUST NOT send a Content-Length header field in any response
   with a status code of 1xx (Informational) or 204 (No Content)."

and com.sun.net.httpserver.HttpExchange#sendResponseHeaders JavaDocs:
- "if {@literal <= -1}, then no response body length is specified and no response body may be written."

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached source code and then:

curl -i "http://localhost:8000/"

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
HTTP/1.1 204 No Content
Date: Sun, 30 Sep 2018 17:08:29 GMT
ACTUAL -
HTTP/1.1 204 No Content
Date: Sun, 30 Sep 2018 17:08:29 GMT
Content-length: 0

---------- BEGIN SOURCE ----------
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

import java.io.IOException;
import java.net.InetSocketAddress;

public class Test {
    public static void main(String[] args) throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
        server.createContext("/", new MyHandler());
        server.setExecutor(null);
        server.start();
    }

    static class MyHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange t) throws IOException {
            t.sendResponseHeaders(204, -1);
        }
    }
}

---------- END SOURCE ----------

FREQUENCY : always



Comments
Fix Request. This fix is important as it resolves an issue where the HTTP server does not correctly implement the semantics of the 204 response code. The fix avoids the issue where the server can send a response body along with a 204 response code ( which is should not allow ). A new automated test has been added, and the existing tests pass successfully. The backport patch applies cleanly.
19-10-2018

Fix will just remove the Content-length header in case of 1XX response or 204. 304 in particular does allow a content-length to be set, but our implementation expects it to be set manually in that case. The test added, tests this case also.
04-10-2018

Good point Michael. I would probably not add any new validation by default - unless this is controlled by e.g. a flag given to the HttpServer at construction time - in order to avoid introducing regressions in existing code. Also it may be useful for testing purposes (e.g. testing an HTTP client API) to be able to create tests servers that are not strictly conformant?
03-10-2018

Dropping the Content-length header from the response in that case is easy to fix. The question is how far to go with validating the input to HttpExchange.sendReponseHeaders(). Perhaps, the spec should be updated to say that IllegalArgumentException can be thrown in cases where the response code is specified as 204, but responseLength > -1. There are many other cases where IAE could be thrown. eg we probably don't want user code generating 1XX responses at all.
03-10-2018

To reproduce the issue, run the attached test case and connect to the server with curl -i "http://localhost:8000/". JDK 8u181 - Fail JDK 11+28 - Fail JDK12-ea+10 - Fail Output : HTTP/1.1 204 No Content Date: Wed, 03 Oct 2018 05:11:12 GMT Content-length: 0
03-10-2018