Skip to content

Commit ec55e42

Browse files
Gregory Vandenbrouckerstoyanchev
authored andcommitted
Full "Forwarded" header support including port number
Issue: SPR-15504
1 parent 2ccf787 commit ec55e42

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,16 @@ UriComponentsBuilder adaptFromForwardedHeaders(HttpHeaders headers) {
717717
String forwardedToUse = StringUtils.tokenizeToStringArray(forwardedHeader, ",")[0];
718718
Matcher matcher = FORWARDED_HOST_PATTERN.matcher(forwardedToUse);
719719
if (matcher.find()) {
720-
host(matcher.group(1).trim());
720+
String hostToUse = matcher.group(1).trim();
721+
int portSeparatorIdx = hostToUse.lastIndexOf(":");
722+
if (portSeparatorIdx > hostToUse.lastIndexOf("]")) {
723+
host(hostToUse.substring(0, portSeparatorIdx));
724+
port(Integer.parseInt(hostToUse.substring(portSeparatorIdx + 1)));
725+
}
726+
else {
727+
host(hostToUse);
728+
port(null);
729+
}
721730
}
722731
matcher = FORWARDED_PROTO_PATTERN.matcher(forwardedToUse);
723732
if (matcher.find()) {

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

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,4 +790,59 @@ public void fromHttpRequestMultipleForwardedHeaderComma() throws Exception {
790790
assertEquals("/rest/mobile/users/1", result.getPath());
791791
}
792792

793+
@Test
794+
public void fromHttpRequestForwardedHeaderWithHostPortAndWithoutServerPort() throws Exception {
795+
MockHttpServletRequest request = new MockHttpServletRequest();
796+
request.addHeader("Forwarded", "proto=https; host=84.198.58.199:9090");
797+
request.setScheme("http");
798+
request.setServerName("example.com");
799+
request.setRequestURI("/rest/mobile/users/1");
800+
801+
HttpRequest httpRequest = new ServletServerHttpRequest(request);
802+
UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
803+
804+
assertEquals("https", result.getScheme());
805+
assertEquals("84.198.58.199", result.getHost());
806+
assertEquals("/rest/mobile/users/1", result.getPath());
807+
assertEquals(9090, result.getPort());
808+
assertEquals("https://84.198.58.199:9090/rest/mobile/users/1", result.toUriString());
809+
}
810+
811+
@Test
812+
public void fromHttpRequestForwardedHeaderWithHostPortAndServerPort() throws Exception {
813+
MockHttpServletRequest request = new MockHttpServletRequest();
814+
request.addHeader("Forwarded", "proto=https; host=84.198.58.199:9090");
815+
request.setScheme("http");
816+
request.setServerPort(8080);
817+
request.setServerName("example.com");
818+
request.setRequestURI("/rest/mobile/users/1");
819+
820+
HttpRequest httpRequest = new ServletServerHttpRequest(request);
821+
UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
822+
823+
assertEquals("https", result.getScheme());
824+
assertEquals("84.198.58.199", result.getHost());
825+
assertEquals("/rest/mobile/users/1", result.getPath());
826+
assertEquals(9090, result.getPort());
827+
assertEquals("https://84.198.58.199:9090/rest/mobile/users/1", result.toUriString());
828+
}
829+
830+
@Test
831+
public void fromHttpRequestForwardedHeaderWithoutHostPortAndWithServerPort() throws Exception {
832+
MockHttpServletRequest request = new MockHttpServletRequest();
833+
request.addHeader("Forwarded", "proto=https; host=84.198.58.199");
834+
request.setScheme("http");
835+
request.setServerPort(8080);
836+
request.setServerName("example.com");
837+
request.setRequestURI("/rest/mobile/users/1");
838+
839+
HttpRequest httpRequest = new ServletServerHttpRequest(request);
840+
UriComponents result = UriComponentsBuilder.fromHttpRequest(httpRequest).build();
841+
842+
assertEquals("https", result.getScheme());
843+
assertEquals("84.198.58.199", result.getHost());
844+
assertEquals("/rest/mobile/users/1", result.getPath());
845+
assertEquals(-1, result.getPort());
846+
assertEquals("https://84.198.58.199/rest/mobile/users/1", result.toUriString());
847+
}
793848
}

0 commit comments

Comments
 (0)