spring-cloud / spring-cloud/spring-cloud-gateway
Query Params (`request.params()`) being decoded while URI (`request.uri()`) is not when before calling downstream services
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 4.9k
- Forks
- 3.5k
- Avg merge
- 20h 57m
- Merged PRs (30d)
- 8
Description
Describe the bug
When passing certain query parameters with encoded characters (like %26) I am expecting that they are passed encoded like this to the downstream services but what is happening is that they are being decoded.
For example, when using the example https://github.com/spencergibb/spring-cloud-gateway-mvc-sample src/main/java/com/example/gatewaymvcsample/Route01FirstRoute.java endpoint passing some encoded characters, we can see that they are being decoded in the parameters
GET localhost:8080/anything/first?company=H%26M&search=one%20two
The other weird part is that the URI is not encoded.
with the & in the parameters, when it calls the downstream services it does not behave well as it thinks is a parameter separation character and not part of the company parameter.
I was able to make it work by creating a before filter and encoding the query parameters before calling the downstream services but for me, it seems a bit of a workaround.
public static Function<ServerRequest, ServerRequest> encodeRequestParameters() {
return request -> ServerRequest.from(request)
.params(queryParams -> queryParams.forEach((key, values) -> {
List<String> modifiedValues = values.stream()
.map(value -> UriUtils.encodeQueryParam(value, StandardCharsets.UTF_8))
.toList();
queryParams.put(key, modifiedValues);
}))
.build();
}
I am not sure which behavior is correct (I think it should remain encoded) but the weird thing is that the parameters and URI are different (one encoded, the other not)
Is this the expected behavior?
Versions:
org.springframework.boot:3.3.2
org.springframework.cloud:spring-cloud-dependencies:2023.0.3
org.springframework.cloud:spring-cloud-gateway-server-mvc:4.1.5
Sample
You can just call the GET localhost:8080/anything/first?company=H%26M&search=one%20two for Route01FirstRoute in the sample project https://github.com/spencergibb/spring-cloud-gateway-mvc-sample
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the request in the spring-cloud-gateway-mvc-sample at src/main/java/com/example/gatewaymvcsample/Route01FirstRoute.java. Compare request.params() with request.uri() for encoded values such as H%26M and one%20two, then trace the downstream call. Done means the handling is consistent with the documented expected behavior for encoded query parameters.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring, spring-boot
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100