Closed chanhyeong closed 10 months ago
Rather than providing your analysis can you share an example of application that shows the issue? It's hard for us to help you as we are missing the entire context.
We wouldn't need a complete example with the gateway but a simple http client request with invalid content length would be enough.
@bclozel
I made a sample in https://github.com/chanhyeong/headersample You can reproduce this issue by following below.
@chanhyeong the project is not accessible.
@bclozel
I'm sorry. I changed visibility as public.
Thanks for the sample. I don't think this issue is related to Spring Framework.
Here, the request body is deserialized from JSON into a Map, then re-serialized as the request body to the proxied service. The "Content-Length" header is copied over directly. I don't think that this should happen. The "Content-Length" header should be overwritten, or the body should never be deserialized in the first place (this is quite inefficient in this case).
You can consider changing your controller to the following:
@PostMapping("/**")
public ResponseEntity<?> serverProxy(
ProxyExchange<byte[]> proxyExchange,
HttpServletRequest request,
@RequestBody byte[] body
) {
String url = assembleUrl(proxyExchange, request);
return proxyExchange.uri(url).body(body).post();
}
I think this has been raised already in spring-cloud/spring-cloud-gateway#3154 and I'll close this issue in favor of that one. There are other workarounds described there, and probably a future fix for this.
Thanks. I doubted because HttpComponentsClientHttpRequest
was changed.
Also, I'm going to add 'Content-Length' header into sensitive headers list temporarily to prevent propagating to downstream. It will be added by httpcore RequestContent.
Affects: 6.1.x
Condition
ProxyExchange
)RestController
)Bug
getContentLength()
value and length of actual value can be different.Content-Length
header in MockHttpServletRequestBuilderContent-Length
header is sent as request header in apache httpcore RequestContentHttpComponentsClientHttpRequest$BodyEntity#getContentLength
This mismatch cause
Connection Reset
-> server wait until receiving 369 bytes, but client sent 125.Before 6.1.x
This issue didn't exist because
HttpComponentsClientHttpRequest
useByteArrayEntity
that contains a serialization result of jackson ObjectMapperhttps://github.com/spring-projects/spring-framework/blob/72835f10b9b07921978da419abf2a182abf67967/spring-web/src/main/java/org/springframework/http/client/HttpComponentsClientHttpRequest.java#L91