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 56a3a94bbb..9842817889 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 @@ -188,7 +188,7 @@ public static Function prefixPath(String prefix) { String newPath = uri.getRawPath() + request.uri().getRawPath(); - URI prefixedUri = UriComponentsBuilder.fromUri(request.uri()).replacePath(newPath).build().toUri(); + URI prefixedUri = UriComponentsBuilder.fromUri(request.uri()).replacePath(newPath).build(true).toUri(); return ServerRequest.from(request).uri(prefixedUri).build(); }; } @@ -211,7 +211,7 @@ public static Function removeRequestParameter(Stri // remove from uri URI newUri = UriComponentsBuilder.fromUri(request.uri()) - .replaceQueryParams(unmodifiableMultiValueMap(queryParams)).build().toUri(); + .replaceQueryParams(unmodifiableMultiValueMap(queryParams)).build(true).toUri(); // remove resolved params from request return ServerRequest.from(request).params(params -> params.remove(name)).uri(newUri).build(); @@ -320,7 +320,7 @@ public static Function rewritePath(String regexp, String path = request.uri().getRawPath(); String newPath = pattern.matcher(path).replaceAll(normalizedReplacement); - URI rewrittenUri = UriComponentsBuilder.fromUri(request.uri()).replacePath(newPath).build().toUri(); + URI rewrittenUri = UriComponentsBuilder.fromUri(request.uri()).replacePath(newPath).build(true).toUri(); ServerRequest modified = ServerRequest.from(request).uri(rewrittenUri).build(); @@ -345,7 +345,7 @@ public static Function setPath(String path) { 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(newPath).build(true).toUri(); return ServerRequest.from(request).uri(prefixedUri).build(); }; } @@ -398,7 +398,7 @@ public static Function stripPrefix(int parts) { } // TODO: end duplicate code from StripPrefixGatewayFilterFactory - URI prefixedUri = UriComponentsBuilder.fromUri(request.uri()).replacePath(newPath.toString()).build() + URI prefixedUri = UriComponentsBuilder.fromUri(request.uri()).replacePath(newPath.toString()).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/ServerMvcIntegrationTests.java b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/ServerMvcIntegrationTests.java index 06bfb43745..d7f46768f0 100644 --- a/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/ServerMvcIntegrationTests.java +++ b/spring-cloud-gateway-server-mvc/src/test/java/org/springframework/cloud/gateway/server/mvc/ServerMvcIntegrationTests.java @@ -53,6 +53,7 @@ import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.cloud.gateway.server.mvc.common.MvcUtils; +import org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions; import org.springframework.cloud.gateway.server.mvc.filter.FormFilter; import org.springframework.cloud.gateway.server.mvc.filter.ForwardedRequestHeadersFilter; import org.springframework.cloud.gateway.server.mvc.filter.XForwardedRequestHeadersFilter; @@ -481,6 +482,15 @@ public void redirectToWorks() { .expectHeader().valueEquals(HttpHeaders.LOCATION, "https://exampleredirect.com"); } + @Test + public void filtersWorksWithEncoding() { + restClient.get().uri("/test-encoding").exchange().expectStatus().isOk() + .expectBody(Map.class).consumeWith(res -> { + Map map = res.getResponseBody(); + assertThat(map.get("url")).asString().endsWith("anything%20goes"); + }); + } + private MultiValueMap> createMultipartData() { ClassPathResource part = new ClassPathResource("test/1x1.png"); MultipartBodyBuilder builder = new MultipartBodyBuilder(); @@ -815,6 +825,19 @@ public RouterFunction gatewayRouterFunctionsStripPrefix() { // @formatter:on } + @Bean + public RouterFunction gatewayRouterFunctionsStripPrefixWithEncoding() { + // @formatter:off + return route(GET("/test-encoding"), http()) + .filter(new HttpbinUriResolver()) + .filter(FilterFunctions.removeRequestParameter("foo")) + .filter(stripPrefix(4)) + .filter(prefixPath("prefix")) + .filter(rewritePath("long", "longer")) + .filter(setPath("/long/path/to/anything/anything goes")); + // @formatter:on + } + @Bean public RouterFunction gatewayRouterFunctionsStripPrefixPost() { // @formatter:off