From a840fca27b1f0e6f4b89734ee7c3a7b9d6956615 Mon Sep 17 00:00:00 2001 From: raccoonback Date: Thu, 15 May 2025 13:19:35 +0900 Subject: [PATCH] Fix improper encoding of '+' in query parameter values when rewrite query parameter Signed-off-by: raccoonback --- .../mvc/filter/BeforeFilterFunctions.java | 2 +- .../filter/BeforeFilterFunctionsTests.java | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctions.java b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctions.java index 6fb71b8d..80e859ac 100644 --- a/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctions.java +++ b/spring-cloud-gateway-server-mvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctions.java @@ -351,7 +351,7 @@ public abstract class BeforeFilterFunctions { queryParams.add(name, replacement); } - MultiValueMap encodedQueryParams = UriUtils.encodeQueryParams(queryParams); + MultiValueMap encodedQueryParams = MvcUtils.encodeQueryParams(queryParams); URI rewrittenUri = UriComponentsBuilder.fromUri(request.uri()) .replaceQueryParams(unmodifiableMultiValueMap(encodedQueryParams)) .build(true) diff --git a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctionsTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctionsTests.java index 0608ca9a..1ef0b2c7 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctionsTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctionsTests.java @@ -129,11 +129,27 @@ class BeforeFilterFunctionsTests { assertThat(result.uri().toString()).hasToString("http://localhost/path?baz=qux&foo%5B%5D=replacement%5B%5D"); } + @Test + void rewritePlusSignRequestParameter() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path") + .param("foo", "bar") + .param("baz", "qux") + .buildRequest(null); + + ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); + + ServerRequest result = BeforeFilterFunctions.rewriteRequestParameter("foo", "replacement+").apply(request); + + assertThat(result.param("foo")).isPresent().hasValue("replacement+"); + assertThat(result.uri().toString()).hasToString("http://localhost/path?baz=qux&foo=replacement%2B"); + } + @Test void rewriteRequestParameterWithEncodedRemainParameters() { MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path") .param("foo", "bar") .param("baz[]", "qux[]") + .param("quux", "corge+") .buildRequest(null); ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); @@ -141,7 +157,8 @@ class BeforeFilterFunctionsTests { ServerRequest result = BeforeFilterFunctions.rewriteRequestParameter("foo", "replacement").apply(request); assertThat(result.param("foo")).isPresent().hasValue("replacement"); - assertThat(result.uri().toString()).hasToString("http://localhost/path?baz%5B%5D=qux%5B%5D&foo=replacement"); + assertThat(result.uri().toString()) + .hasToString("http://localhost/path?baz%5B%5D=qux%5B%5D&quux=corge%2B&foo=replacement"); } @Test