Skip to content

Commit 5f868b4

Browse files
rwinchrstoyanchev
authored andcommitted
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
1 parent 147368e commit 5f868b4

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
7979

8080
private boolean removeOnly;
8181

82+
private boolean requestOnly;
83+
8284

8385
public ForwardedHeaderFilter() {
8486
this.pathHelper = new UrlPathHelper();
@@ -97,6 +99,20 @@ public void setRemoveOnly(boolean removeOnly) {
9799
this.removeOnly = removeOnly;
98100
}
99101

102+
/**
103+
* Enables mode in which only the HttpServletRequest is modified. This means that
104+
* {@link HttpServletResponse#sendRedirect(String)} will only work when the application is configured to use
105+
* relative redirects. This can be done with Servlet Container specific setup. For example, using Tomcat's
106+
* <a href="https://tomcat.apache.org/tomcat-8.0-doc/config/context.html#Common_Attributes">useRelativeRedirects</a>
107+
* attribute.
108+
*
109+
* @param requestOnly whether to customize the {@code HttpServletResponse} or not. Default is false (customize the
110+
* {@code HttpServletResponse})
111+
* @since 4.3.10
112+
*/
113+
public void setRequestOnly(boolean requestOnly) {
114+
this.requestOnly = requestOnly;
115+
}
100116

101117
@Override
102118
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
@@ -130,7 +146,8 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
130146
}
131147
else {
132148
HttpServletRequest theRequest = new ForwardedHeaderExtractingRequest(request, this.pathHelper);
133-
HttpServletResponse theResponse = new ForwardedHeaderExtractingResponse(response, theRequest);
149+
HttpServletResponse theResponse = this.requestOnly ? response :
150+
new ForwardedHeaderExtractingResponse(response, theRequest);
134151
filterChain.doFilter(theRequest, theResponse);
135152
}
136153
}

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,26 @@ public void sendRedirectWithNoXForwardedAndDotDotPath() throws Exception {
403403
assertEquals("../foo/bar", redirectedUrl);
404404
}
405405

406+
@Test
407+
public void sendRedirectWhenRequestOnlyAndXForwardedThenUsesRelativeRedirects() throws Exception {
408+
this.request.addHeader(X_FORWARDED_PROTO, "https");
409+
this.request.addHeader(X_FORWARDED_HOST, "example.com");
410+
this.request.addHeader(X_FORWARDED_PORT, "443");
411+
this.filter.setRequestOnly(true);
412+
413+
String location = sendRedirect("/a");
414+
415+
assertEquals("/a", location);
416+
}
417+
418+
@Test
419+
public void sendRedirectWhenRequestOnlyAndNoXForwardedThenUsesRelativeRedirects() throws Exception {
420+
this.filter.setRequestOnly(true);
421+
422+
String location = sendRedirect("/a");
423+
424+
assertEquals("/a", location);
425+
}
406426

407427
private String sendRedirect(final String location) throws ServletException, IOException {
408428
MockHttpServletResponse response = doWithFiltersAndGetResponse(this.filter, new OncePerRequestFilter() {

0 commit comments

Comments
 (0)