Merge branch '5.1.x'

This commit is contained in:
Rossen Stoyanchev
2019-07-15 11:34:35 +01:00
3 changed files with 228 additions and 18 deletions

View File

@@ -158,6 +158,12 @@ public class ForwardedHeaderFilter extends OncePerRequestFilter {
}
}
@Override
protected void doFilterNestedErrorDispatch(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
doFilterInternal(request, response, filterChain);
}
/**
* Hide "Forwarded" or "X-Forwarded-*" headers.

View File

@@ -94,10 +94,19 @@ public abstract class OncePerRequestFilter extends GenericFilterBean {
HttpServletResponse httpResponse = (HttpServletResponse) response;
String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
alreadyFilteredAttributeName = updateForErrorDispatch(alreadyFilteredAttributeName, request);
boolean hasAlreadyFilteredAttribute = request.getAttribute(alreadyFilteredAttributeName) != null;
if (hasAlreadyFilteredAttribute || skipDispatch(httpRequest) || shouldNotFilter(httpRequest)) {
if (skipDispatch(httpRequest) || shouldNotFilter(httpRequest)) {
// Proceed without invoking this filter...
filterChain.doFilter(request, response);
}
else if (hasAlreadyFilteredAttribute) {
if (DispatcherType.ERROR.equals(request.getDispatcherType())) {
doFilterNestedErrorDispatch(httpRequest, httpResponse, filterChain);
return;
}
// Proceed without invoking this filter...
filterChain.doFilter(request, response);
@@ -115,7 +124,6 @@ public abstract class OncePerRequestFilter extends GenericFilterBean {
}
}
private boolean skipDispatch(HttpServletRequest request) {
if (isAsyncDispatch(request) && shouldNotFilterAsyncDispatch()) {
return true;
@@ -167,21 +175,6 @@ public abstract class OncePerRequestFilter extends GenericFilterBean {
return name + ALREADY_FILTERED_SUFFIX;
}
private String updateForErrorDispatch(String alreadyFilteredAttributeName, ServletRequest request) {
// Jetty does ERROR dispatch within sendError, so request attribute is still present
// Use a separate attribute for ERROR dispatches
if (DispatcherType.ERROR.equals(request.getDispatcherType()) && !shouldNotFilterErrorDispatch() &&
request.getAttribute(alreadyFilteredAttributeName) != null) {
return alreadyFilteredAttributeName + ".ERROR";
}
return alreadyFilteredAttributeName;
}
/**
* Can be overridden in subclasses for custom filtering control,
* returning {@code true} to avoid filtering of the given request.
@@ -238,4 +231,23 @@ public abstract class OncePerRequestFilter extends GenericFilterBean {
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException;
/**
* Typically an ERROR dispatch happens after the REQUEST dispatch completes,
* and the filter chain starts anew. On some servers however the ERROR
* dispatch may be nested within the REQUEST dispatch, e.g. as a result of
* calling {@code sendError} on the response. In that case we are still in
* the filter chain, on the same thread, but the request and response have
* been switched to the original, unwrapped ones.
* <p>Sub-classes may use this method to filter such nested ERROR dispatches
* and re-apply wrapping on the request or response. {@code ThreadLocal}
* context, if any, should still be active as we are still nested within
* the filter chain.
* @since 5.1.9
*/
protected void doFilterNestedErrorDispatch(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
doFilter(request, response, filterChain);
}
}