spring-cloud-gateway: gateway-mvc: chunked responses with status 500 are damaged

Describe the bug Trying to proxy 500 response with “Transfer-Encoding:chunked” damages message body by eliminating chunk length from the body and as a result getting:

curl: (56) Illegal or missing hexadecimal sequence in chunked-encoding Chunked errors with 4xx codes processed correctly

Sample

  1. Create service that returns 500 error with “Transfer-Encoding: chunked”
  2. Proxy GET request there
  3. Test with curl -v http://service/url Response: curl: (56) Illegal or missing hexadecimal sequence in chunked-encoding Using tcpdump you can see that service response comes with 500 and chunk size. After request processing by ProxyExchage header still contains “Transfer-Encoding:chunked”, but no chunks data is in the body of the message.

Service 500 chunked response: image

Proxied 500 “chunked” response: image

Spring Cloud version: Hoxton.SR1

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 16 (2 by maintainers)

Most upvoted comments

Investigating the problem a bit more have found that error happens only with default Tomcat servlet container. Switching to Jetty or Undertow fixes the problem.

@vadimkim Hello ? I have reduced the problem just whithout using spring cloud gateway mvc

    @GetMapping("/proxy500")
    public ResponseEntity<?> proxy500(ProxyExchange<byte[]> proxy) {
       MultiValueMap<String, String> multiValueMap = new HttpHeaders();
       multiValueMap.put("Transfer-Encoding", Collections.singletonList("chunked"));
        multiValueMap.put("Connection", Collections.singletonList("close"));
        return new ResponseEntity<>("{", multiValueMap, HttpStatus.INTERNAL_SERVER_ERROR);

    }
}

and this is the reuslt

curl http://localhost:8080/api/v1/proxy500 -vvv
*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /api/v1/proxy500 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 500 
< Transfer-Encoding: chunked
< Connection: close
< Content-Type: text/plain;charset=UTF-8
< Date: Sat, 14 Mar 2020 16:15:17 GMT
< 
* Illegal or missing hexadecimal sequence in chunked-encoding
* stopped the pause stream!
* Closing connection 0
curl: (56) Illegal or missing hexadecimal sequence in chunked-encoding

and it worked ok with jetty I try to find out the reason from source code of tomcat, may be is caused by spring mvc. It is really a hard job. I really hope you or anybody from spring team can help me.I keep working now.

@taojiaenx please look at the topic - the problem is not related to spring-cloud-gateway that is reactive. It is related to module spring-cloud-gateway-mvc. It is stand-alone component that uses basically just one class - ProxyExchange. For MVC application the default servlet container is Tomcat. You can download test example and see there are just 2 lines of code. If you tell me which Spring Boot configuration property is responsible for persistent Tomcat connection I will add it to application.properties and test again. I didn’t find it at documentation.

Sure. Here it is. There are 2 projects - api (to generate 500) and proxy (to proxy to api). URL-s are hard-coded. Just run both projects and execute: $ curl -v http://localhost:8080/api/v1/proxy500 test.zip Expected behavior: to get 500 error with payload Actual behavior: curl: (56) Illegal or missing hexadecimal sequence in chunked-encoding