Full "Forwarded" header support including port number

Issue: SPR-15504
This commit is contained in:
Gregory Vandenbroucke
2017-04-28 20:36:13 +02:00
committed by Rossen Stoyanchev
parent ee40310c92
commit 554c3f3d7e
2 changed files with 69 additions and 11 deletions

View File

@@ -677,7 +677,7 @@ public class UriComponentsBuilder implements Cloneable {
String forwardedToUse = StringUtils.tokenizeToStringArray(forwardedHeader, ",")[0];
Matcher matcher = FORWARDED_HOST_PATTERN.matcher(forwardedToUse);
if (matcher.find()) {
host(matcher.group(1).trim());
adaptForwardedHost(matcher.group(1).trim());
}
matcher = FORWARDED_PROTO_PATTERN.matcher(forwardedToUse);
if (matcher.find()) {
@@ -687,16 +687,7 @@ public class UriComponentsBuilder implements Cloneable {
else {
String hostHeader = headers.getFirst("X-Forwarded-Host");
if (StringUtils.hasText(hostHeader)) {
String hostToUse = StringUtils.tokenizeToStringArray(hostHeader, ",")[0];
int portSeparatorIdx = hostToUse.lastIndexOf(":");
if (portSeparatorIdx > hostToUse.lastIndexOf("]")) {
host(hostToUse.substring(0, portSeparatorIdx));
port(Integer.parseInt(hostToUse.substring(portSeparatorIdx + 1)));
}
else {
host(hostToUse);
port(null);
}
adaptForwardedHost(StringUtils.tokenizeToStringArray(hostHeader, ",")[0]);
}
String portHeader = headers.getFirst("X-Forwarded-Port");
@@ -718,6 +709,18 @@ public class UriComponentsBuilder implements Cloneable {
return this;
}
private void adaptForwardedHost(String hostToUse) {
int portSeparatorIdx = hostToUse.lastIndexOf(":");
if (portSeparatorIdx > hostToUse.lastIndexOf("]")) {
host(hostToUse.substring(0, portSeparatorIdx));
port(Integer.parseInt(hostToUse.substring(portSeparatorIdx + 1)));
}
else {
host(hostToUse);
port(null);
}
}
private void resetHierarchicalComponents() {
this.userInfo = null;
this.host = null;

View File

@@ -782,4 +782,59 @@ public class UriComponentsBuilderTests {
assertEquals("/rest/mobile/users/1", result.getPath());
}
@Test
public void fromHttpRequestForwardedHeaderWithHostPortAndWithoutServerPort() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Forwarded", "proto=https; host=84.198.58.199:9090");
request.setScheme("http");
request.setServerName("example.com");
request.setRequestURI("/rest/mobile/users/1");
HttpRequest httpRequest = new ServletServerHttpRequest(request);
UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
assertEquals("https", result.getScheme());
assertEquals("84.198.58.199", result.getHost());
assertEquals("/rest/mobile/users/1", result.getPath());
assertEquals(9090, result.getPort());
assertEquals("https://84.198.58.199:9090/rest/mobile/users/1", result.toUriString());
}
@Test
public void fromHttpRequestForwardedHeaderWithHostPortAndServerPort() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Forwarded", "proto=https; host=84.198.58.199: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();
assertEquals("https", result.getScheme());
assertEquals("84.198.58.199", result.getHost());
assertEquals("/rest/mobile/users/1", result.getPath());
assertEquals(9090, result.getPort());
assertEquals("https://84.198.58.199:9090/rest/mobile/users/1", result.toUriString());
}
@Test
public void fromHttpRequestForwardedHeaderWithoutHostPortAndWithServerPort() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
request.addHeader("Forwarded", "proto=https; host=84.198.58.199");
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();
assertEquals("https", result.getScheme());
assertEquals("84.198.58.199", result.getHost());
assertEquals("/rest/mobile/users/1", result.getPath());
assertEquals(-1, result.getPort());
assertEquals("https://84.198.58.199/rest/mobile/users/1", result.toUriString());
}
}