From 1f10961bd729559ed043cb2fdf6f8e3d47fa484f Mon Sep 17 00:00:00 2001 From: spring-builds Date: Thu, 13 Mar 2025 13:28:24 +0000 Subject: [PATCH 1/4] Bumping versions Signed-off-by: raccoonback --- README.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.adoc b/README.adoc index 9d84e36e..d4195c40 100644 --- a/README.adoc +++ b/README.adoc @@ -224,7 +224,7 @@ Spring Cloud Build brings along the `basepom:duplicate-finder-maven-plugin`, th [[duplicate-finder-configuration]] === Duplicate Finder configuration -Duplicate finder is *enabled by default* and will run in the `verify` phase of your Maven build, but it will only take effect in your project if you add the `duplicate-finder-maven-plugin` to the `build` section of the projecst's `pom.xml`. +Duplicate finder is *enabled by default* and will run in the `verify` phase of your Maven build, but it will only take effect in your project if you add the `duplicate-finder-maven-plugin` to the `build` section of the project's `pom.xml`. .pom.xml [source,xml] From 07aca3e63e7279e9265779083a416848e5af238d Mon Sep 17 00:00:00 2001 From: raccoonback Date: Sun, 5 Jan 2025 15:54:56 +0900 Subject: [PATCH 2/4] Prevent double encoding in setPath method The setPath method was causing URLs to be encoded twice under certain conditions. This fix ensures proper handling of parameters to avoid redundant encoding. Signed-off-by: raccoonback --- .../mvc/filter/BeforeFilterFunctions.java | 6 +- .../filter/BeforeFilterFunctionsTests.java | 160 ++++++++++++++++++ 2 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctionsTests.java 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 93a3eb7c..4f273ea2 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 @@ -350,9 +350,11 @@ public abstract class BeforeFilterFunctions { return request -> { Map uriVariables = MvcUtils.getUriTemplateVariables(request); URI uri = uriTemplate.expand(uriVariables); - String newPath = uri.getRawPath(); - URI prefixedUri = UriComponentsBuilder.fromUri(request.uri()).replacePath(newPath).build().toUri(); + URI prefixedUri = UriComponentsBuilder.fromUri(request.uri()) + .replacePath(uri.getRawPath()) + .build(true) + .toUri(); return ServerRequest.from(request).uri(prefixedUri).build(); }; } 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 new file mode 100644 index 00000000..d72fe496 --- /dev/null +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/filter/BeforeFilterFunctionsTests.java @@ -0,0 +1,160 @@ +/* + * Copyright 2013-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.gateway.server.mvc.filter; + +import java.util.Collections; + +import org.junit.jupiter.api.Test; + +import org.springframework.mock.web.MockHttpServletRequest; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.web.servlet.function.ServerRequest; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author raccoonback + */ +class BeforeFilterFunctionsTests { + + @Test + void rewriteRequestParameter() { + 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"); + } + + @Test + void rewriteOnlyFirstRequestParameter() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path") + .param("foo", "bar_1") + .param("foo", "bar_2") + .param("foo", "bar_3") + .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"); + } + + @Test + void rewriteEncodedRequestParameter() { + 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%5B%5D=replacement%5B%5D"); + } + + @Test + void rewriteRequestParameterWithEncodedRemainParameters() { + 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%5B%5D=qux%5B%5D&foo=replacement"); + } + + @Test + void rewriteRequestParameterWithEncodedPath() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path/é/last") + .param("foo", "bar") + .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/%C3%A9/last?foo=replacement"); + } + + @Test + void setPath() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/legacy/path") + .buildRequest(null); + + ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); + + ServerRequest result = BeforeFilterFunctions.setPath("/new/path").apply(request); + + assertThat(result.uri().toString()).isEqualTo("http://localhost/new/path"); + } + + @Test + void setEncodedPath() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/legacy/path") + .buildRequest(null); + + ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); + + ServerRequest result = BeforeFilterFunctions.setPath("/new/é").apply(request); + + assertThat(result.uri().toString()).isEqualTo("http://localhost/new/%C3%A9"); + } + + @Test + void setPathWithParameters() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/legacy/path") + .queryParam("foo", "bar") + .buildRequest(null); + + ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); + + ServerRequest result = BeforeFilterFunctions.setPath("/new/path").apply(request); + + assertThat(result.uri().toString()).isEqualTo("http://localhost/new/path?foo=bar"); + } + + @Test + void setPathWithEncodedParameters() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/legacy/path") + .queryParam("foo[]", "bar[]") + .buildRequest(null); + + ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); + + ServerRequest result = BeforeFilterFunctions.setPath("/new/path").apply(request); + + assertThat(result.uri().toString()).isEqualTo("http://localhost/new/path?foo%5B%5D=bar%5B%5D"); + } + +} From 962c8c34e5b631a9839ec5dfa74ef50b051538b0 Mon Sep 17 00:00:00 2001 From: raccoonback Date: Sun, 5 Jan 2025 15:57:37 +0900 Subject: [PATCH 3/4] Prevent double encoding in stripPrefix method The stripPrefix method was causing URLs to be encoded twice under certain conditions. This fix ensures proper handling of parameters to avoid redundant encoding. Signed-off-by: raccoonback --- .../mvc/filter/BeforeFilterFunctions.java | 2 +- .../filter/BeforeFilterFunctionsTests.java | 38 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) 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 4f273ea2..bf4a5180 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 @@ -409,7 +409,7 @@ public abstract class BeforeFilterFunctions { URI prefixedUri = UriComponentsBuilder.fromUri(request.uri()) .replacePath(newPath.toString()) - .build() + .build(true) .toUri(); return ServerRequest.from(request).uri(prefixedUri).build(); }; 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 d72fe496..7944baac 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 @@ -157,4 +157,42 @@ class BeforeFilterFunctionsTests { assertThat(result.uri().toString()).isEqualTo("http://localhost/new/path?foo%5B%5D=bar%5B%5D"); } + @Test + void stripPrefix() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/depth1/depth2/depth3") + .buildRequest(null); + + ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); + + ServerRequest result = BeforeFilterFunctions.stripPrefix(2).apply(request); + + assertThat(result.uri().toString()).isEqualTo("http://localhost/depth3"); + } + + @Test + void stripPrefixWithEncodedPath() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/depth1/depth2/depth3/é") + .buildRequest(null); + + ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); + + ServerRequest result = BeforeFilterFunctions.stripPrefix(2).apply(request); + + assertThat(result.uri().toString()).isEqualTo("http://localhost/depth3/%C3%A9"); + } + + @Test + void stripPrefixWithEncodedParameters() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/depth1/depth2/depth3") + .queryParam("baz[]", "qux[]") + .buildRequest(null); + + ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); + + ServerRequest result = BeforeFilterFunctions.stripPrefix(2).apply(request); + + assertThat(result.param("baz[]")).isPresent().hasValue("qux[]"); + assertThat(result.uri().toString()).isEqualTo("http://localhost/depth3?baz%5B%5D=qux%5B%5D"); + } + } From 478fab319f43efd0d6fe7e1df893493158164429 Mon Sep 17 00:00:00 2001 From: raccoonback Date: Fri, 14 Mar 2025 08:10:03 +0900 Subject: [PATCH 4/4] Prevent double encoding in removeRequestParameter method The removeRequestParameter method was causing URLs to be encoded twice under certain conditions. This fix ensures proper handling of parameters to avoid redundant encoding. Signed-off-by: raccoonback --- .../mvc/filter/BeforeFilterFunctions.java | 7 +- .../filter/BeforeFilterFunctionsTests.java | 172 ++++++++---------- 2 files changed, 84 insertions(+), 95 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 bf4a5180..650f9ca6 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 @@ -45,6 +45,7 @@ import org.springframework.web.server.ResponseStatusException; import org.springframework.web.servlet.function.ServerRequest; import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriTemplate; +import org.springframework.web.util.UriUtils; import static org.springframework.cloud.gateway.server.mvc.common.MvcUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR; import static org.springframework.util.CollectionUtils.unmodifiableMultiValueMap; @@ -214,10 +215,12 @@ public abstract class BeforeFilterFunctions { MultiValueMap queryParams = new LinkedMultiValueMap<>(request.params()); queryParams.remove(name); + MultiValueMap encodedQueryParams = UriUtils.encodeQueryParams(queryParams); + // remove from uri URI newUri = UriComponentsBuilder.fromUri(request.uri()) - .replaceQueryParams(unmodifiableMultiValueMap(queryParams)) - .build() + .replaceQueryParams(unmodifiableMultiValueMap(encodedQueryParams)) + .build(true) .toUri(); // remove resolved params from request 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 7944baac..095ec4f9 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 @@ -31,168 +31,154 @@ import static org.assertj.core.api.Assertions.assertThat; */ class BeforeFilterFunctionsTests { - @Test - void rewriteRequestParameter() { - 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"); - } - - @Test - void rewriteOnlyFirstRequestParameter() { - MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path") - .param("foo", "bar_1") - .param("foo", "bar_2") - .param("foo", "bar_3") - .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"); - } - - @Test - void rewriteEncodedRequestParameter() { - 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%5B%5D=replacement%5B%5D"); - } - - @Test - void rewriteRequestParameterWithEncodedRemainParameters() { - 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%5B%5D=qux%5B%5D&foo=replacement"); - } - - @Test - void rewriteRequestParameterWithEncodedPath() { - MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path/é/last") - .param("foo", "bar") - .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/%C3%A9/last?foo=replacement"); - } - @Test void setPath() { MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/legacy/path") - .buildRequest(null); + .buildRequest(null); ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); ServerRequest result = BeforeFilterFunctions.setPath("/new/path").apply(request); - assertThat(result.uri().toString()).isEqualTo("http://localhost/new/path"); + assertThat(result.uri().toString()).hasToString("http://localhost/new/path"); } @Test void setEncodedPath() { MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/legacy/path") - .buildRequest(null); + .buildRequest(null); ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); ServerRequest result = BeforeFilterFunctions.setPath("/new/é").apply(request); - assertThat(result.uri().toString()).isEqualTo("http://localhost/new/%C3%A9"); + assertThat(result.uri().toString()).hasToString("http://localhost/new/%C3%A9"); } @Test void setPathWithParameters() { MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/legacy/path") - .queryParam("foo", "bar") - .buildRequest(null); + .queryParam("foo", "bar") + .buildRequest(null); ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); ServerRequest result = BeforeFilterFunctions.setPath("/new/path").apply(request); - assertThat(result.uri().toString()).isEqualTo("http://localhost/new/path?foo=bar"); + assertThat(result.uri().toString()).hasToString("http://localhost/new/path?foo=bar"); } @Test void setPathWithEncodedParameters() { MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/legacy/path") - .queryParam("foo[]", "bar[]") - .buildRequest(null); + .queryParam("foo[]", "bar[]") + .buildRequest(null); ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); ServerRequest result = BeforeFilterFunctions.setPath("/new/path").apply(request); - assertThat(result.uri().toString()).isEqualTo("http://localhost/new/path?foo%5B%5D=bar%5B%5D"); + assertThat(result.uri().toString()).hasToString("http://localhost/new/path?foo%5B%5D=bar%5B%5D"); + } + + @Test + void removeRequestParameter() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path") + .queryParam("foo", "bar") + .queryParam("baz", "qux") + .buildRequest(null); + + ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); + + ServerRequest result = BeforeFilterFunctions.removeRequestParameter("foo").apply(request); + + assertThat(result.param("foo")).isEmpty(); + assertThat(result.param("baz")).isPresent().hasValue("qux"); + assertThat(result.uri().toString()).hasToString("http://localhost/path?baz=qux"); + } + + @Test + void removeEncodedRequestParameter() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path") + .queryParam("foo[]", "bar") + .queryParam("baz", "qux") + .buildRequest(null); + + ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); + + ServerRequest result = BeforeFilterFunctions.removeRequestParameter("foo[]").apply(request); + + assertThat(result.param("foo[]")).isEmpty(); + assertThat(result.param("baz")).isPresent().hasValue("qux"); + assertThat(result.uri().toString()).hasToString("http://localhost/path?baz=qux"); + } + + @Test + void removeRequestParameterWithEncodedRemainParameters() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path") + .queryParam("foo", "bar") + .queryParam("baz[]", "qux[]") + .buildRequest(null); + + ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); + + ServerRequest result = BeforeFilterFunctions.removeRequestParameter("foo").apply(request); + + assertThat(result.param("foo")).isEmpty(); + assertThat(result.param("baz[]")).isPresent().hasValue("qux[]"); + assertThat(result.uri().toString()).hasToString("http://localhost/path?baz%5B%5D=qux%5B%5D"); + } + + @Test + void removeRequestParameterWithEncodedPath() { + MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/é") + .queryParam("foo", "bar") + .buildRequest(null); + + ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); + + ServerRequest result = BeforeFilterFunctions.removeRequestParameter("foo").apply(request); + + assertThat(result.param("foo")).isEmpty(); + assertThat(result.uri().toString()).hasToString("http://localhost/%C3%A9"); } @Test void stripPrefix() { MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/depth1/depth2/depth3") - .buildRequest(null); + .buildRequest(null); ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); ServerRequest result = BeforeFilterFunctions.stripPrefix(2).apply(request); - assertThat(result.uri().toString()).isEqualTo("http://localhost/depth3"); + assertThat(result.uri().toString()).hasToString("http://localhost/depth3"); } @Test void stripPrefixWithEncodedPath() { MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/depth1/depth2/depth3/é") - .buildRequest(null); + .buildRequest(null); ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); ServerRequest result = BeforeFilterFunctions.stripPrefix(2).apply(request); - assertThat(result.uri().toString()).isEqualTo("http://localhost/depth3/%C3%A9"); + assertThat(result.uri().toString()).hasToString("http://localhost/depth3/%C3%A9"); } @Test void stripPrefixWithEncodedParameters() { MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/depth1/depth2/depth3") - .queryParam("baz[]", "qux[]") - .buildRequest(null); + .queryParam("baz[]", "qux[]") + .buildRequest(null); ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList()); ServerRequest result = BeforeFilterFunctions.stripPrefix(2).apply(request); assertThat(result.param("baz[]")).isPresent().hasValue("qux[]"); - assertThat(result.uri().toString()).isEqualTo("http://localhost/depth3?baz%5B%5D=qux%5B%5D"); + assertThat(result.uri().toString()).hasToString("http://localhost/depth3?baz%5B%5D=qux%5B%5D"); } }