From c07d7692351f72fce5502cdc4f461b957b429713 Mon Sep 17 00:00:00 2001 From: sgibb Date: Tue, 19 Mar 2024 13:49:48 -0400 Subject: [PATCH] Handles encoded uri parts in AddRequestParameterGatewayFilterFactory Fixes gh-2726 --- ...dRequestParameterGatewayFilterFactory.java | 7 ++++-- ...estParameterGatewayFilterFactoryTests.java | 22 +++++++++++++++---- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/AddRequestParameterGatewayFilterFactory.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/AddRequestParameterGatewayFilterFactory.java index d99c46a7..a9c01416 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/AddRequestParameterGatewayFilterFactory.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/AddRequestParameterGatewayFilterFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2024 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. @@ -29,6 +29,7 @@ import org.springframework.web.server.ServerWebExchange; import org.springframework.web.util.UriComponentsBuilder; import static org.springframework.cloud.gateway.support.GatewayToStringStyler.filterToStringCreator; +import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.containsEncodedParts; /** * @author Spencer Gibb @@ -57,8 +58,10 @@ public class AddRequestParameterGatewayFilterFactory extends AbstractNameValueGa query.append('='); query.append(value); + boolean encoded = containsEncodedParts(uri); try { - URI newUri = UriComponentsBuilder.fromUri(uri).replaceQuery(query.toString()).build(true).toUri(); + URI newUri = UriComponentsBuilder.fromUri(uri).replaceQuery(query.toString()).build(encoded) + .toUri(); ServerHttpRequest request = exchange.getRequest().mutate().uri(newUri).build(); diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/AddRequestParameterGatewayFilterFactoryTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/AddRequestParameterGatewayFilterFactoryTests.java index cdd5b089..0c5a1000 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/AddRequestParameterGatewayFilterFactoryTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/AddRequestParameterGatewayFilterFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013-2020 the original author or authors. + * Copyright 2013-2024 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. @@ -68,11 +68,21 @@ public class AddRequestParameterGatewayFilterFactoryTests extends BaseWebClientT testRequestParameterFilter("www.addreqparamjava.org", "ValueB-www", "javaname", "%E6%89%8E%E6%A0%B9"); } + @Test + public void addRequestParameterFilterWorksEncodedPathSegmentJavaDsl() { + testRequestParameterFilter("www.addreqparamjavaencodedsegment.org", "/anything/test%20", "ValueB-www", + "javaname", "%E6%89%8E%E6%A0%B9"); + } + private void testRequestParameterFilter(String name, String value) { testRequestParameterFilter("www.addrequestparameter.org", "ValueA", name, value); } private void testRequestParameterFilter(String host, String expectedValue, String name, String value) { + testRequestParameterFilter(host, "/get", expectedValue, name, value); + } + + private void testRequestParameterFilter(String host, String path, String expectedValue, String name, String value) { String query; if (name != null) { query = "?" + name + "=" + value; @@ -80,7 +90,7 @@ public class AddRequestParameterGatewayFilterFactoryTests extends BaseWebClientT else { query = ""; } - URI uri = UriComponentsBuilder.fromUriString(this.baseUri + "/get" + query).build(true).toUri(); + URI uri = UriComponentsBuilder.fromUriString(this.baseUri + path + query).build(true).toUri(); boolean checkForEncodedValue = containsEncodedParts(uri); testClient.get().uri(uri).header("Host", host).exchange().expectBody(Map.class).consumeWith(response -> { Map args = getMap(response.getResponseBody(), "args"); @@ -118,8 +128,12 @@ public class AddRequestParameterGatewayFilterFactoryTests extends BaseWebClientT @Bean public RouteLocator testRouteLocator(RouteLocatorBuilder builder) { - return builder.routes().route("add_request_param_java_test", - r -> r.path("/get").and().host("{sub}.addreqparamjava.org") + return builder.routes() + .route("add_request_param_java_test", r -> r.path("/get").and().host("{sub}.addreqparamjava.org") + .filters(f -> f.prefixPath("/httpbin").addRequestParameter("example", "ValueB-{sub}")) + .uri(uri)) + .route("add_request_param_java_test_encoded_segment", r -> r.path("/anything/{segment}").and() + .host("{sub}.addreqparamjavaencodedsegment.org") .filters(f -> f.prefixPath("/httpbin").addRequestParameter("example", "ValueB-{sub}")) .uri(uri)) .build();