Summary
HttpClient will no longer send the Content-Length header on HTTP/1.1 requests when there is no content to send and the request method is neither POST nor PUT. This includes requests created using the HttpRequest.newBuilder().method(methodName, BodyPublishers.noBody()).
Problem
RFC 9110: Http Semantics indicates that the content-length request header should not be sent when the content length is zero link:
A user agent SHOULD send Content-Length in a request when the method defines a meaning for enclosed content and it is not sending Transfer-Encoding. For example, a user agent normally sends Content-Length in a POST request even when the value is 0 (indicating empty content). A user agent SHOULD NOT send a Content-Length header field when the request message does not contain content and the method semantics do not anticipate such data.
The form with no content-length header is supposed to be equivalent to the form with content-length equal to zero, and the RFC recommends using the shorter form except where the server might expect some content to be sent.
To further complicate the situation, users are permitted to define custom HTTP methods, and there's no way to tell if a custom method expects content or not.
Users reported that certain server fails on GET requests with content-length headers and works correctly without them, see link
Solution
When there's no content to include in a request, do not send content-length header unless the method is POST or PUT. This appears to follow the RFC 9110 recommendation.
Alternatives considered:
- Always send content-length (this is the current behavior). This is suboptimal, and doesn't follow the RFC recommendations.
- never send content-length. This is the optimal behavior, but doesn't follow the RFC recommendations either.
- special-case all RFC 9110 methods other than POST and PUT to omit the content-length header, send the header otherwise. This appears to follow the RFC recommendation, but unlike the selected solution, would send content-length on custom methods with no content
- special-case the BodyPublishers.noBody publisher, but send content-length for other publishers even when they publish no content. This would enable the API user to decide whether the content-length header should be sent or not.
Specification
No specification changes. For description of behavior changes see the "Solution" section above.
- csr of
-
JDK-8358942 HttpClient adds Content-Length: 0 for a GET request with a BodyPublishers.noBody()
-
- Open
-