helidon-io / helidon

Java libraries for writing microservices
https://helidon.io
Apache License 2.0
3.5k stars 566 forks source link

Helidon-Se: 4.1.0 500 error when there is no-content instead of 204 #9396

Open ksivap147 opened 21 hours ago

ksivap147 commented 21 hours ago

Environment Details


Problem Description

I am seeing this behavior with Helidon 4.1.0 w.r.t 204 Status Code and gzip encoding. Client is sending a POST request for which there is no data, so the server sets status to 204 and does not send any content. When there is no Accept-Encoding in request, client gets 204 and no body. But when Accept-Encoding is gzip, even though I am sending a status of 204, client gets a 500. With this in the server log: Attempt to send status 500 Internal Server Error with entity. Server responded with Internal Server Error. Please fix your routing, this is not allowed by HTTP specification, such responses MUST NOT contain an entity. I believe this is because of the "Transfer-Encoding" header being added with value as chunked.

Request without gzip:

curl --request POST \ --url http://100.111.154.123:8080/extract/ap \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --data '....'

status:

204 No Content

Response headers:

Content-Length: 0 Strict-Transport-Security: max-age=31536000; includeSubDomains opc-request-id: /50cbc6a4b355b1a7bc19c5761f1bec38/50cbc6a4b355b1a7bc19c5761f1bec38

Request with gzip:

curl --request POST \ --url http://100.111.154.123:8080/extract/ap \ --header 'Accept: application/json' \ --header 'Accept-Encoding: gzip' \ --header 'Content-Type: application/json' \ --data '...'

status:

500 Internal Server Error

Response headers:

Content-Encoding: gzip Strict-Transport-Security: max-age=31536000; includeSubDomains Transfer-Encoding: chunked

Steps to reproduce

{"timestamp":"2024-10-15 16:33:56.371","level":"DEBUG","thread":"[0x5be9f214 0x7d7d8914] WebServer socket","mdc":{"_SP":"//","spanId":"5fbe38894fb1a62b","traceId":"5ada9aaa45df1f701ea1cce1a015d3be"},"logger":"io.helidon.webserver.http1.Http1LoggingConnectionListener.send","message":"[0x5be9f214 0x7d7d8914] send status: 204 No Content"} {"timestamp":"2024-10-15 16:33:56.371","level":"DEBUG","thread":"[0x5be9f214 0x7d7d8914] WebServer socket","mdc":{"_SP":"//","spanId":"5fbe38894fb1a62b","traceId":"5ada9aaa45df1f701ea1cce1a015d3be"},"logger":"io.helidon.webserver.http1.Http1LoggingConnectionListener.send","message":"[0x5be9f214 0x7d7d8914] send headers: Content-Encoding: gzip Strict-Transport-Security: max-age=31536000; includeSubDomains Transfer-Encoding: chunked opc-request-id: /5ada9aaa45df1f701ea1cce1a015d3be/5ada9aaa45df1f701ea1cce1a015d3be "} {"timestamp":"2024-10-15 16:33:56.371","level":"ERROR","thread":"[0x5be9f214 0x7d7d8914] WebServer socket","mdc":{"_SP":"//","spanId":"5fbe38894fb1a62b","traceId":"5ada9aaa45df1f701ea1cce1a015d3be"},"logger":"io.helidon.webserver.http1.Http1ServerResponse","message":"Attempt to send status 500 Internal Server Error with entity. Server responded with Internal Server Error. Please fix your routing, this is not allowed by HTTP specification, such responses MUST NOT contain an entity."}

ksivap147 commented 17 hours ago

I see, it is being set JDK HttpServer. Is Helidon webserver internally using this library? https://github.com/openjdk/jdk/blob/master/src/jdk.httpserver/share/classes/sun/net/httpserver/ExchangeImpl.java if (contentLen == 0) { if (http10) { o.setWrappedStream (new UndefLengthOutputStream (this, ros)); close = true; } else { rspHdrs.set ("Transfer-encoding", "chunked"); o.setWrappedStream (new ChunkedOutputStream (this, ros)); } }