Search code examples
javaspringhttpjetty

Jetty 12 Spring 6 missing Content-Length in response


Jetty 12 with Spring 6 do not set in response Content-Length or Transfer-Encoding:chunked when using HttpMessageConverter (GsonHttpMessageConverter in my example) and client sends request with Connection:close header.

Here is a request to a simple servlet:

$ curl -v -X POST -H "Connection:close" -H "Content-Type: application/json" http://localhost:1221/abc/simple
*   Trying 127.0.0.1:1221...
* Connected to localhost (127.0.0.1) port 1221 (#0)
> POST /abc/simple HTTP/1.1
> Host: localhost:1221
> User-Agent: curl/7.81.0
> Accept: */*
> Connection:close
> Content-Type: application/json
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: Jetty(12.0.2)
< Date: Mon, 15 Jan 2024 19:16:17 GMT
< Content-Type: application/json;charset=utf-8
< Content-Length: 2
< Connection: close
<
* Closing connection 0
{}

Compare with a request to Spring controller which uses HttpMessageConverter:

$ curl -v -X POST -H "Connection:close" -H "Content-Type: application/json" -d '{"input":"aaa"}' http://localhost:1221/abc/controller/
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 127.0.0.1:1221...
* Connected to localhost (127.0.0.1) port 1221 (#0)
> POST /abc/controller/ HTTP/1.1
> Host: localhost:1221
> User-Agent: curl/7.81.0
> Accept: */*
> Connection:close
> Content-Type: application/json
> Content-Length: 15
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: Jetty(12.0.2)
< Date: Mon, 15 Jan 2024 19:16:52 GMT
< Content-Type: application/json;charset=utf-8
< Connection: close
<
* Closing connection 0
{"msg":"aaa"}

No Content-Length or Transfer-Encoding:chunked in response. But one of them should be there according to https://datatracker.ietf.org/doc/html/rfc2616#section-4.4.

Also I tried Jetty 11 Spring5/6, Jetty 9 Spring 4 - same results.

See example in https://github.com/techsup69/jetty-cont-len-12 for Jetty12 Spring 6.

Somebody knows why is Jetty/Spring acting like this?


Solution

  • RFC2616 is obsolete.

    Jetty 12 defaults to RFC7230 behaviors when it comes to HTTP/1.x behaviors.

    Now to what's happening, since you specified Connection: close on the request, that means the Connection: close on the response is the indication that the response body is complete once the connection is closed.

    This is mentioned in paragraph 2 of Section 3 of RFC7230.

    If you do not specify Connection: close you will get the Transfer-Encoding: chunked to satisfy the persistent connection requirements.

    This behavior (called a "close-delimited message") has been consistent in Jetty for quite a number of years. But should it still do that? Probably not in light of RFC7230 section 3.3.3 Message Body Length.

    So I opened https://github.com/jetty/jetty.project/issues/11277