spring-cloud / spring-cloud/spring-cloud-gateway

Query Params (`request.params()`) being decoded while URI (`request.uri()`) is not when before calling downstream services

Open
#3,494 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

waiting-for-triage
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

image

The other weird part is that the URI is not encoded.

image

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.