diff --git a/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java b/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java index c16fb46f9b..ba2ad448c6 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java @@ -39,13 +39,14 @@ import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UrlPathHelper; + /** * Filter that wraps the request in order to override its * {@link HttpServletRequest#getServerName() getServerName()}, * {@link HttpServletRequest#getServerPort() getServerPort()}, * {@link HttpServletRequest#getScheme() getScheme()}, and * {@link HttpServletRequest#isSecure() isSecure()} methods with values derived - * from "Fowarded" or "X-Forwarded-*" headers. In effect the wrapped request + * from "Forwarded" or "X-Forwarded-*" headers. In effect the wrapped request * reflects the client-originated protocol and address. * * @author Rossen Stoyanchev @@ -57,11 +58,12 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter { private static final Set FORWARDED_HEADER_NAMES; static { - FORWARDED_HEADER_NAMES = new HashSet(4); + FORWARDED_HEADER_NAMES = new HashSet(5); FORWARDED_HEADER_NAMES.add("Forwarded"); FORWARDED_HEADER_NAMES.add("X-Forwarded-Host"); FORWARDED_HEADER_NAMES.add("X-Forwarded-Port"); FORWARDED_HEADER_NAMES.add("X-Forwarded-Proto"); + FORWARDED_HEADER_NAMES.add("X-Forwarded-Prefix"); } @@ -133,6 +135,7 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter { private final Map> headers; + public ForwardedHeaderRequestWrapper(HttpServletRequest request, ContextPathHelper pathHelper) { super(request); @@ -145,32 +148,23 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter { this.host = uriComponents.getHost(); this.port = (port == -1 ? (this.secure ? 443 : 80) : port); - this.contextPath = contextPath(request, pathHelper); - this.requestUri = requestUri(request, pathHelper); + this.contextPath = initContextPath(request, pathHelper); + this.requestUri = initRequestUri(request, pathHelper); this.requestUrl = initRequestUrl(this.scheme, this.host, port, this.requestUri); - this.headers = initHeaders(request); } - private static String contextPath(HttpServletRequest request, ContextPathHelper pathHelper) { + + private static String initContextPath(HttpServletRequest request, ContextPathHelper pathHelper) { String contextPath = (pathHelper != null ? pathHelper.getContextPath(request) : request.getContextPath()); return prependForwardedPrefix(request, contextPath); } - private static String requestUri(HttpServletRequest request, ContextPathHelper pathHelper) { + private static String initRequestUri(HttpServletRequest request, ContextPathHelper pathHelper) { String requestUri = (pathHelper != null ? pathHelper.getRequestUri(request) : request.getRequestURI()); return prependForwardedPrefix(request, requestUri); } - private static String prependForwardedPrefix(HttpServletRequest request, String value) { - String header = request.getHeader("X-Forwarded-Prefix"); - if (StringUtils.hasText(header)) { - value = header + value; - } - UriComponents uriComponents = UriComponentsBuilder.fromUriString(value).build(); - return uriComponents.toUriString(); - } - private static StringBuffer initRequestUrl(String scheme, String host, int port, String path) { StringBuffer sb = new StringBuffer(); sb.append(scheme).append("://").append(host); @@ -195,6 +189,17 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter { return headers; } + private static String prependForwardedPrefix(HttpServletRequest request, String value) { + String header = request.getHeader("X-Forwarded-Prefix"); + if (StringUtils.hasText(header)) { + while (header.endsWith("/")) { + header = header.substring(0, header.length() - 1); + } + value = header + value; + } + return value; + } + @Override public String getScheme() { diff --git a/spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java index c6d54b22bd..4c9c45256f 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java @@ -35,6 +35,7 @@ import static org.junit.Assert.assertTrue; /** * Unit tests for {@link ForwardedHeaderFilter}. * @author Rossen Stoyanchev + * @author EddĂș MelĂ©ndez */ public class ForwardedHeaderFilterTests { @@ -176,8 +177,7 @@ public class ForwardedHeaderFilterTests { this.request.setRequestURI("/mvc-showcase"); HttpServletRequest actual = filterAndGetWrappedRequest(); - assertEquals("http://localhost/prefix/mvc-showcase", actual.getRequestURL() - .toString()); + assertEquals("http://localhost/prefix/mvc-showcase", actual.getRequestURL().toString()); } @Test @@ -186,8 +186,7 @@ public class ForwardedHeaderFilterTests { this.request.setRequestURI("/mvc-showcase"); HttpServletRequest actual = filterAndGetWrappedRequest(); - assertEquals("http://localhost/prefix/mvc-showcase", actual.getRequestURL() - .toString()); + assertEquals("http://localhost/prefix/mvc-showcase", actual.getRequestURL().toString()); } @Test