From 1e90d029735e809a8ddb1c60f35e76083b1fe084 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 30 Jul 2013 11:40:54 -0400 Subject: [PATCH] Fix issue with parsing x-forwarded-host header Issue: SPR-10701 --- .../support/ServletUriComponentsBuilder.java | 17 ++++++++++++++--- .../ServletUriComponentsBuilderTests.java | 18 ++++++++++++++++-- 2 files changed, 30 insertions(+), 5 deletions(-) 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 7ad0d49b78..bda44896e0 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 @@ -94,9 +94,20 @@ public class ServletUriComponentsBuilder extends UriComponentsBuilder { public static ServletUriComponentsBuilder fromRequest(HttpServletRequest request) { String scheme = request.getScheme(); int port = request.getServerPort(); - - String header = request.getHeader("X-Forwarded-Host"); - String host = StringUtils.hasText(header) ? header: request.getServerName(); + String host = request.getServerName(); + + String xForwardedHostHeader = request.getHeader("X-Forwarded-Host"); + + if (StringUtils.hasText(xForwardedHostHeader)) { + if (StringUtils.countOccurrencesOf(xForwardedHostHeader, ":") == 1) { + String[] hostAndPort = StringUtils.split(xForwardedHostHeader, ":"); + host = hostAndPort[0]; + port = Integer.parseInt(hostAndPort[1]); + } + else { + host = xForwardedHostHeader; + } + } ServletUriComponentsBuilder builder = new ServletUriComponentsBuilder(); builder.scheme(scheme); 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 02ee04662d..b7cf39d9f0 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 @@ -16,13 +16,14 @@ package org.springframework.web.servlet.support; -import static org.junit.Assert.assertEquals; - import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.util.UriComponents; + +import static org.junit.Assert.*; /** * @author Rossen Stoyanchev @@ -93,6 +94,19 @@ public class ServletUriComponentsBuilderTests { assertEquals("http://anotherHost/mvc-showcase/data/param?foo=123", result); } + // SPR-10701 + + @Test + public void fromRequestWithForwardedHostAndPortHeader() { + request.addHeader("X-Forwarded-Host", "webtest.foo.bar.com:443"); + request.setRequestURI("/mvc-showcase/data/param"); + request.setQueryString("foo=123"); + UriComponents result = ServletUriComponentsBuilder.fromRequest(request).build(); + + assertEquals("webtest.foo.bar.com", result.getHost()); + assertEquals(443, result.getPort()); + } + @Test public void fromContextPath() { request.setRequestURI("/mvc-showcase/data/param");