Skip to content

Gateway MVC forward request but with decoded parameters (%2B becomes +) #3346

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
lohoso opened this issue Apr 10, 2024 · 4 comments
Closed

Comments

@lohoso
Copy link

lohoso commented Apr 10, 2024

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 #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?
spring-projects/spring-framework#23025

@rworsnop
Copy link

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.

@Nhoutain
Copy link

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)

@cuizhanming
Copy link

This is still bug in 4.2.x

@ryanjbaxter
Copy link
Contributor

Seems like this might be a duplicate of #3759. There is a PR to fix this #3789

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants