Skip to content

ProxyExchange fails with "IOException: insufficient data written" with boot 3.2 #3154

@jkuipers

Description

@jkuipers

The ProxyExchange type in spring-cloud-gateway-mvc copies over the headers from the incoming request, unless they're marked as sensitive. In addition, it also uses the HTTP message converters to unmarshal the payload of the incoming request and marshal it again when sending.
What we found is that in the header copying, it also includes the Content-Length header of the incoming request. However, b/o the unmarshalling and then marshalling the content length of the proxied request can be different: especially in the case of JSON where whitespace is removed, it can become less.

This causes problems with some downstream servers, as they keep waiting for additional request contents based on the erroneous Content-Length header. When not using smth like Apache Component HTTP client but using the default Java client instead, this even leads to errors in the client itself (showcased in attached sample).

This behavior was not there in previous versions: actually, with Spring Boot 3.1.6 and the underlying Spring web version this works. When you check what's being sent then you can see that a Content-Length header is always set, with the correct value.
It looks like the latest Spring web code (Jackson HTTP message converter?) no longer sets its own Content-Length header when marshalling to JSON. Therefore, spring-cloud-gateway-mvc should never copy over this header from the incoming request, but should rather leave it up to the RestTemplate to either leave it out or set this to the correct value for the outgoing request.

BTW, although this isn't strictly related to this issue, I believe that the Host header of the incoming request shouldn't be copied either by default: this can also lead to issues.

Sample
I've attached a project with two integration tests that showcase the problem. By configuring the content-length to be a sensitive header you can work around the issue, but users of the framework should not be required to do this.
gateway-mvc-contentlength.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions