Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8369533

HttpClient adds Content-Length: 0 for a GET request with a BodyPublishers.noBody()

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Unresolved
    • Icon: P4 P4
    • 26
    • core-libs
    • None
    • behavioral
    • minimal
    • Hide
      The current HttpClient behavior is unrecommended, but not prohibited by the spec. Still, a server out in the wild was found that refused to accept it.

      If we change the behavior, we might encounter other servers that will refuse to cooperate.

      It is possible for user code to override the supplied content-length value after removing it from restricted headers, but not to completely remove the header.

      If the header is not present however, it is possible for user code to add it.
      Whereas the current behavior offers no workaround, the proposed behavior will have one.

      The restriction on content-length header can be removed by setting the system property "jdk.httpclient.allowRestrictedHeaders" to "content-length"
      Show
      The current HttpClient behavior is unrecommended, but not prohibited by the spec. Still, a server out in the wild was found that refused to accept it. If we change the behavior, we might encounter other servers that will refuse to cooperate. It is possible for user code to override the supplied content-length value after removing it from restricted headers, but not to completely remove the header. If the header is not present however, it is possible for user code to add it. Whereas the current behavior offers no workaround, the proposed behavior will have one. The restriction on content-length header can be removed by setting the system property "jdk.httpclient.allowRestrictedHeaders" to "content-length"
    • Java API
    • JDK

      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.

            djelinski Daniel Jelinski
            jpai Jaikiran Pai
            Daniel Fuchs
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: