Problem
we experiences error as pic shown when receiving response from backend service rm-client-backend, which serves as a proxy routing http call.
Reason
The reason the error above is happening is our service has been built with Golang 1.15+. Before Golang 1.15, duplicated transfer-encoding headers or headers with two values were permitted by Golang's proxy roundTrip. However, starting in Golang 1.15+, the implementation is more strict. Specifically, the router is now rejecting responses from applications with either multiple transfer encodings or out-of-spec "identity" encoding values. Golang 1.15 is more strict about the Transfer Encoding header to prevent a well-known request smuggling vulnerability, as well as mitigate a broad class of security issues around this header over time.
Why backend application have multiple transfer encodings?
An application proxies requests (like a gateway) and the proxy/gateway app is naïvely copying all headers between the client and backend application. This can cause issues because you may copy a transfer encoding header added by the server to which you're communicating and also have the proxy server add in a second transfer-encoding header, which can trigger the error. It is incorrect for a proxy/gateway application to copy the transfer-encoding header, which is a hop-by-hop header
More specifically, In backend proxy service, when using RestTemplate from a Controller annotated class and returning the result of RestTemplate.exchange in a method that returns a ResponseEntity. Similar to situation #1, this will cause a problem if the microservice to which you are talking returns a transfer-encoding header because RestTemplate.exchange will copy all of the response headers from the client response into the ResponseEntity it creates, including the transfer-encoding header.
Solution
Issue can be mitigated by not directly returning ResponseEntity objects from RestTemplate.exchange. You need to first remove the transfer-encoding header, if it's present. You could directly modify that object in your Controller before returning it, but that could get repetitive across many methods and many controllers. A less invasive way of doing this would be with a RestTemplate interceptor.