Skip to content

Commit 07d2c08

Browse files
committed
Do not tokenize Forward header value
This commit remove the tokenization previously used in UriComponentsBuilder#adaptFromForwardedHeaders, in order to support Forwarded headers that have multiple, comma-separated 'for' elements. Closes gh-25737
1 parent ed3b7cd commit 07d2c08

File tree

2 files changed

+22
-3
lines changed

2 files changed

+22
-3
lines changed

spring-web/src/main/java/org/springframework/web/util/UriComponentsBuilder.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,7 @@ UriComponentsBuilder adaptFromForwardedHeaders(HttpHeaders headers) {
754754
try {
755755
String forwardedHeader = headers.getFirst("Forwarded");
756756
if (StringUtils.hasText(forwardedHeader)) {
757-
String forwardedToUse = StringUtils.tokenizeToStringArray(forwardedHeader, ",")[0];
758-
Matcher matcher = FORWARDED_PROTO_PATTERN.matcher(forwardedToUse);
757+
Matcher matcher = FORWARDED_PROTO_PATTERN.matcher(forwardedHeader);
759758
if (matcher.find()) {
760759
scheme(matcher.group(1).trim());
761760
port(null);
@@ -764,7 +763,7 @@ else if (isForwardedSslOn(headers)) {
764763
scheme("https");
765764
port(null);
766765
}
767-
matcher = FORWARDED_HOST_PATTERN.matcher(forwardedToUse);
766+
matcher = FORWARDED_HOST_PATTERN.matcher(forwardedHeader);
768767
if (matcher.find()) {
769768
adaptForwardedHost(matcher.group(1).trim());
770769
}

spring-web/src/test/java/org/springframework/web/util/UriComponentsBuilderTests.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,26 @@ void fromHttpRequestForwardedHeaderWithProtoAndServerPort() {
11141114
assertThat(result.toUriString()).isEqualTo("https://example.com/rest/mobile/users/1");
11151115
}
11161116

1117+
@Test // gh-25737
1118+
void fromHttpRequestForwardedHeaderComma() {
1119+
MockHttpServletRequest request = new MockHttpServletRequest();
1120+
request.addHeader("Forwarded", "for=192.0.2.0,for=192.0.2.1;proto=https;host=192.0.2.3:9090");
1121+
request.setScheme("http");
1122+
request.setServerPort(8080);
1123+
request.setServerName("example.com");
1124+
request.setRequestURI("/rest/mobile/users/1");
1125+
1126+
HttpRequest httpRequest = new ServletServerHttpRequest(request);
1127+
UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
1128+
1129+
assertThat(result.getScheme()).isEqualTo("https");
1130+
assertThat(result.getHost()).isEqualTo("192.0.2.3");
1131+
assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
1132+
assertThat(result.getPort()).isEqualTo(9090);
1133+
assertThat(result.toUriString()).isEqualTo("https://192.0.2.3:9090/rest/mobile/users/1");
1134+
}
1135+
1136+
11171137
@Test // SPR-16364
11181138
void uriComponentsNotEqualAfterNormalization() {
11191139
UriComponents uri1 = UriComponentsBuilder.fromUriString("http://test.com").build().normalize();

0 commit comments

Comments
 (0)