Skip to content

Commit

Permalink
Do not tokenize Forward header value
Browse files Browse the repository at this point in the history
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
  • Loading branch information
poutsma committed Sep 9, 2020
1 parent ed3b7cd commit 07d2c08
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
Expand Up @@ -754,8 +754,7 @@ UriComponentsBuilder adaptFromForwardedHeaders(HttpHeaders headers) {
try {
String forwardedHeader = headers.getFirst("Forwarded");
if (StringUtils.hasText(forwardedHeader)) {
String forwardedToUse = StringUtils.tokenizeToStringArray(forwardedHeader, ",")[0];
Matcher matcher = FORWARDED_PROTO_PATTERN.matcher(forwardedToUse);
Matcher matcher = FORWARDED_PROTO_PATTERN.matcher(forwardedHeader);
if (matcher.find()) {
scheme(matcher.group(1).trim());
port(null);
Expand All @@ -764,7 +763,7 @@ else if (isForwardedSslOn(headers)) {
scheme("https");
port(null);
}
matcher = FORWARDED_HOST_PATTERN.matcher(forwardedToUse);
matcher = FORWARDED_HOST_PATTERN.matcher(forwardedHeader);
if (matcher.find()) {
adaptForwardedHost(matcher.group(1).trim());
}
Expand Down
Expand Up @@ -1114,6 +1114,26 @@ void fromHttpRequestForwardedHeaderWithProtoAndServerPort() {
assertThat(result.toUriString()).isEqualTo("https://example.com/rest/mobile/users/1");
}

@Test // gh-25737
void fromHttpRequestForwardedHeaderComma() {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Forwarded", "for=192.0.2.0,for=192.0.2.1;proto=https;host=192.0.2.3:9090");
request.setScheme("http");
request.setServerPort(8080);
request.setServerName("example.com");
request.setRequestURI("/rest/mobile/users/1");

HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();

assertThat(result.getScheme()).isEqualTo("https");
assertThat(result.getHost()).isEqualTo("192.0.2.3");
assertThat(result.getPath()).isEqualTo("/rest/mobile/users/1");
assertThat(result.getPort()).isEqualTo(9090);
assertThat(result.toUriString()).isEqualTo("https://192.0.2.3:9090/rest/mobile/users/1");
}


@Test // SPR-16364
void uriComponentsNotEqualAfterNormalization() {
UriComponents uri1 = UriComponentsBuilder.fromUriString("http://test.com").build().normalize();
Expand Down

0 comments on commit 07d2c08

Please sign in to comment.