Browse Source

Add ForwardedHeaderFilter requestOnly

Add an option for ForwardedHeaderFilter to only process the
HttpServletRequest. This means that HttpServletResponse.sendRedirect will
only work when the application is conifgured to use relative redirects
using Servlet Container specific setup.

Issue: SPR-15717
pull/1480/merge
Rob Winch 7 years ago committed by Rossen Stoyanchev
parent
commit
5f868b493a
  1. 19
      spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java
  2. 20
      spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java

19
spring-web/src/main/java/org/springframework/web/filter/ForwardedHeaderFilter.java

@ -79,6 +79,8 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter { @@ -79,6 +79,8 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
private boolean removeOnly;
private boolean requestOnly;
public ForwardedHeaderFilter() {
this.pathHelper = new UrlPathHelper();
@ -97,6 +99,20 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter { @@ -97,6 +99,20 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
this.removeOnly = removeOnly;
}
/**
* Enables mode in which only the HttpServletRequest is modified. This means that
* {@link HttpServletResponse#sendRedirect(String)} will only work when the application is configured to use
* relative redirects. This can be done with Servlet Container specific setup. For example, using Tomcat's
* <a href="https://tomcat.apache.org/tomcat-8.0-doc/config/context.html#Common_Attributes">useRelativeRedirects</a>
* attribute.
*
* @param requestOnly whether to customize the {@code HttpServletResponse} or not. Default is false (customize the
* {@code HttpServletResponse})
* @since 4.3.10
*/
public void setRequestOnly(boolean requestOnly) {
this.requestOnly = requestOnly;
}
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
@ -130,7 +146,8 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter { @@ -130,7 +146,8 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
}
else {
HttpServletRequest theRequest = new ForwardedHeaderExtractingRequest(request, this.pathHelper);
HttpServletResponse theResponse = new ForwardedHeaderExtractingResponse(response, theRequest);
HttpServletResponse theResponse = this.requestOnly ? response :
new ForwardedHeaderExtractingResponse(response, theRequest);
filterChain.doFilter(theRequest, theResponse);
}
}

20
spring-web/src/test/java/org/springframework/web/filter/ForwardedHeaderFilterTests.java

@ -403,6 +403,26 @@ public class ForwardedHeaderFilterTests { @@ -403,6 +403,26 @@ public class ForwardedHeaderFilterTests {
assertEquals("../foo/bar", redirectedUrl);
}
@Test
public void sendRedirectWhenRequestOnlyAndXForwardedThenUsesRelativeRedirects() throws Exception {
this.request.addHeader(X_FORWARDED_PROTO, "https");
this.request.addHeader(X_FORWARDED_HOST, "example.com");
this.request.addHeader(X_FORWARDED_PORT, "443");
this.filter.setRequestOnly(true);
String location = sendRedirect("/a");
assertEquals("/a", location);
}
@Test
public void sendRedirectWhenRequestOnlyAndNoXForwardedThenUsesRelativeRedirects() throws Exception {
this.filter.setRequestOnly(true);
String location = sendRedirect("/a");
assertEquals("/a", location);
}
private String sendRedirect(final String location) throws ServletException, IOException {
MockHttpServletResponse response = doWithFiltersAndGetResponse(this.filter, new OncePerRequestFilter() {

Loading…
Cancel
Save