diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java index d9879dbe6f..47110b2ba5 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/ServletUriComponentsBuilder.java @@ -111,6 +111,7 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder { } else { host = hostToUse; + port = -1; } } @@ -119,6 +120,11 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder { port = Integer.parseInt(portHeader); } + String protocolHeader = request.getHeader("X-Forwarded-Proto"); + if (StringUtils.hasText(protocolHeader)) { + scheme = protocolHeader; + } + ServletUriComponentsBuilder builder = new ServletUriComponentsBuilder(); builder.scheme(scheme); builder.host(host); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/ServletUriComponentsBuilderTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/ServletUriComponentsBuilderTests.java index 16560cec29..5933cc4022 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/ServletUriComponentsBuilderTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/ServletUriComponentsBuilderTests.java @@ -133,6 +133,33 @@ public class ServletUriComponentsBuilderTests { assertEquals(9090, uriComponents.getPort()); } + // SPR-11872 + + @Test + public void fromRequestWithForwardedHostWithDefaultPort() { + this.request.setServerPort(10080); + this.request.addHeader("X-Forwarded-Host", "example.org"); + UriComponents result = ServletUriComponentsBuilder.fromRequest(request).build(); + + assertEquals("example.org", result.getHost()); + assertEquals("should have used the default port of the forwarded request", + -1, result.getPort()); + } + + @Test + public void fromRequestWithForwardedHostWithForwardedScheme() { + this.request.setServerPort(10080); + this.request.addHeader("X-Forwarded-Proto", "https"); + this.request.addHeader("X-Forwarded-Host", "example.org"); + UriComponents result = ServletUriComponentsBuilder.fromRequest(request).build(); + + assertEquals("example.org", result.getHost()); + assertEquals("should have derived scheme from header", + "https", result.getScheme()); + assertEquals("should have used the default port of the forwarded request", + -1, result.getPort()); + } + @Test public void fromContextPath() { request.setRequestURI("/mvc-showcase/data/param");