Gateway MVC forward request but with decoded parameters (%2B becomes +)
Describe the bug I use the following version of Spring Cloud Gateway MVC to forward request. org.springframework.cloud spring-cloud-starter-gateway-mvc 4.1.2
same description as https://github.com/spring-cloud/spring-cloud-gateway/issues/3272 a bug in the code of the ProxyExchangeHandlerFunction class.
boolean encoded = containsEncodedQuery(serverRequest.uri());
// @formatter:off
URI url = UriComponentsBuilder.fromUri(serverRequest.uri())
.scheme(uri.getScheme())
.host(uri.getHost())
.port(uri.getPort())
.replaceQueryParams(serverRequest.params())
.build(encoded)
.toUri();
This is based on serverRequest.uri() to determine whether the URL has been encoded, but when constructing a new URL, the query parameter is replaced with serverRequest.params(). The reality is that serverRequest.uri() is encoded by the URI, but serverRequest.params() is not encoded.
Sample The url as http://localhost:8083/test?q=name%3Atestname%2BState%3AFailed In Gateway MVC will forward the rquest as http://localhost:8083/test?q=name:testname+State:Failed, when the corrsponding service receive the request, then + becomes space character.
For the UriComponentsBuilder, it will use HierarchicalUriComponents internally, is this related to below issue? https://github.com/spring-projects/spring-framework/issues/23025
containsEncodedQuery can also cause double-encoding. If the (decoded!) query param contains a non-standard char, it will assume everything is not encoded and encode the whole thing again.
Is there any news on this one? I'm using spring boot 3.3.6 with spring-cloud-gateway-server-mvc 4.1.6 (based on spring-cloud-dependencies 2023.0.5)
I faced the same issue where my parameter filters=%5B%5D is forwarded to the downstream service with filters=[] which lead to 400 from the downstream service.
The definition of the route is quite simple:
// Assure service is a variable with service name while url is the downstream service url
route(service.toLowerCase())
.add(RouterFunctions.route(RequestPredicates.all().and(path(service.toLowerCase() + "/**")), http(url.toString())))
.filter(stripPrefix(1))
.build()
When debugging, it look like this reply point the root cause, but I still have it in spring-cloud 4.1.6
Is there, at least, any workaround?
I'm a bit confused that such basic core feature of a gateway seems to not work when migrate to the new version. I already faced this issue, which has been solved since (I copy the fix in a new stripPrefix)
This is still bug in 4.2.x
Seems like this might be a duplicate of https://github.com/spring-cloud/spring-cloud-gateway/issues/3759. There is a PR to fix this https://github.com/spring-cloud/spring-cloud-gateway/pull/3789