Skip to content

Commit 330a43d

Browse files
committed
Fix improper encoding of '+' in query parameter values
Signed-off-by: raccoonback <kosb15@naver.com>
1 parent 98021b5 commit 330a43d

File tree

5 files changed

+49
-4
lines changed

5 files changed

+49
-4
lines changed

spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/RemoveRequestParameterGatewayFilterFactory.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424

2525
import org.springframework.cloud.gateway.filter.GatewayFilter;
2626
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
27+
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
2728
import org.springframework.http.server.reactive.ServerHttpRequest;
2829
import org.springframework.util.LinkedMultiValueMap;
2930
import org.springframework.util.MultiValueMap;
3031
import org.springframework.web.server.ServerWebExchange;
3132
import org.springframework.web.util.UriComponentsBuilder;
32-
import org.springframework.web.util.UriUtils;
3333

3434
import static org.springframework.cloud.gateway.support.GatewayToStringStyler.filterToStringCreator;
3535
import static org.springframework.util.CollectionUtils.unmodifiableMultiValueMap;
@@ -59,7 +59,8 @@ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
5959
queryParams.remove(config.getName());
6060

6161
try {
62-
MultiValueMap<String, String> encodedQueryParams = UriUtils.encodeQueryParams(queryParams);
62+
MultiValueMap<String, String> encodedQueryParams = ServerWebExchangeUtils
63+
.encodeQueryParams(queryParams);
6364
URI newUri = UriComponentsBuilder.fromUri(request.getURI())
6465
.replaceQueryParams(unmodifiableMultiValueMap(encodedQueryParams))
6566
.build(true)

spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/filter/factory/RewriteRequestParameterGatewayFilterFactory.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@
2424

2525
import org.springframework.cloud.gateway.filter.GatewayFilter;
2626
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
27+
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
2728
import org.springframework.http.server.reactive.ServerHttpRequest;
2829
import org.springframework.util.Assert;
2930
import org.springframework.util.LinkedMultiValueMap;
3031
import org.springframework.util.MultiValueMap;
3132
import org.springframework.web.server.ServerWebExchange;
3233
import org.springframework.web.util.UriComponentsBuilder;
33-
import org.springframework.web.util.UriUtils;
3434

3535
import static org.springframework.cloud.gateway.support.GatewayToStringStyler.filterToStringCreator;
3636
import static org.springframework.util.CollectionUtils.unmodifiableMultiValueMap;
@@ -71,7 +71,8 @@ public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
7171
}
7272

7373
try {
74-
MultiValueMap<String, String> encodedQueryParams = UriUtils.encodeQueryParams(queryParams);
74+
MultiValueMap<String, String> encodedQueryParams = ServerWebExchangeUtils
75+
.encodeQueryParams(queryParams);
7576
URI uri = uriComponentsBuilder.replaceQueryParams(unmodifiableMultiValueMap(encodedQueryParams))
7677
.build(true)
7778
.toUri();

spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/support/ServerWebExchangeUtils.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
package org.springframework.cloud.gateway.support;
1818

1919
import java.net.URI;
20+
import java.nio.charset.StandardCharsets;
2021
import java.util.Collections;
2122
import java.util.HashMap;
2223
import java.util.LinkedHashSet;
24+
import java.util.List;
2325
import java.util.Locale;
2426
import java.util.Map;
2527
import java.util.Set;
@@ -48,9 +50,13 @@
4850
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
4951
import org.springframework.http.server.reactive.ServerHttpResponse;
5052
import org.springframework.util.Assert;
53+
import org.springframework.util.CollectionUtils;
54+
import org.springframework.util.LinkedMultiValueMap;
55+
import org.springframework.util.MultiValueMap;
5156
import org.springframework.web.reactive.DispatcherHandler;
5257
import org.springframework.web.server.ServerWebExchange;
5358
import org.springframework.web.util.UriComponentsBuilder;
59+
import org.springframework.web.util.UriUtils;
5460

5561
/**
5662
* @author Spencer Gibb
@@ -260,6 +266,17 @@ public static boolean containsEncodedParts(URI uri) {
260266
return encoded;
261267
}
262268

269+
public static MultiValueMap<String, String> encodeQueryParams(MultiValueMap<String, String> params) {
270+
MultiValueMap<String, String> encodedQueryParams = new LinkedMultiValueMap<>(params.size());
271+
for (Map.Entry<String, List<String>> entry : params.entrySet()) {
272+
for (String value : entry.getValue()) {
273+
encodedQueryParams.add(UriUtils.encode(entry.getKey(), StandardCharsets.UTF_8),
274+
UriUtils.encode(value, StandardCharsets.UTF_8));
275+
}
276+
}
277+
return CollectionUtils.unmodifiableMultiValueMap(encodedQueryParams);
278+
}
279+
263280
public static HttpStatus parse(String statusString) {
264281
HttpStatus httpStatus;
265282

spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RemoveRequestParameterGatewayFilterFactoryTests.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.cloud.gateway.filter.factory;
1818

19+
import java.net.URI;
20+
1921
import org.junit.jupiter.api.BeforeEach;
2022
import org.junit.jupiter.api.Test;
2123
import org.mockito.ArgumentCaptor;
@@ -24,6 +26,7 @@
2426
import org.springframework.cloud.gateway.filter.GatewayFilter;
2527
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
2628
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory.NameConfig;
29+
import org.springframework.http.HttpMethod;
2730
import org.springframework.http.server.reactive.ServerHttpRequest;
2831
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
2932
import org.springframework.mock.web.server.MockServerWebExchange;
@@ -123,6 +126,23 @@ void removeRequestParameterFilterShouldHandleRemainingParamsWhichRequiringEncodi
123126
assertThat(actualRequest.getQueryParams()).containsEntry("ccc", singletonList(",xyz"));
124127
}
125128

129+
@Test
130+
void removeRequestParameterFilterShouldHandleRemainingPlusSignParams() {
131+
MockServerHttpRequest request = MockServerHttpRequest
132+
.method(HttpMethod.GET, URI.create("http://localhost?foo=bar&aaa=%2Bxyz"))
133+
.build();
134+
exchange = MockServerWebExchange.from(request);
135+
NameConfig config = new NameConfig();
136+
config.setName("foo");
137+
GatewayFilter filter = new RemoveRequestParameterGatewayFilterFactory().apply(config);
138+
139+
filter.filter(exchange, filterChain);
140+
141+
ServerHttpRequest actualRequest = captor.getValue().getRequest();
142+
assertThat(actualRequest.getQueryParams()).doesNotContainKey("foo");
143+
assertThat(actualRequest.getQueryParams()).containsEntry("aaa", singletonList("+xyz"));
144+
}
145+
126146
@Test
127147
void removeRequestParameterFilterShouldHandleEncodedParameterName() {
128148
MockServerHttpRequest request = MockServerHttpRequest.get("http://localhost")

spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/filter/factory/RewriteRequestParameterGatewayFilterFactoryTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ void rewriteRequestParameterFilterKeepsOtherParamsEncoded() {
8888
Map.of("campaign[]", List.of("blue"), "color", List.of("white")));
8989
}
9090

91+
@Test
92+
void rewriteRequestParameterFilterWithPlusSign() {
93+
testRewriteRequestParameterFilter("color", "white+", "campaign=blue%2B&color=green",
94+
Map.of("campaign", List.of("blue+"), "color", List.of("white+")));
95+
}
96+
9197
private void testRewriteRequestParameterFilter(String name, String replacement, String query,
9298
Map<String, List<String>> expectedQueryParams) {
9399
GatewayFilter filter = new RewriteRequestParameterGatewayFilterFactory()

0 commit comments

Comments
 (0)