From 9f8148419f4d6235be3e24dd8296b22983edca81 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 7 Jun 2019 16:07:56 -0400 Subject: [PATCH] Separate "filtered" attribute for ERROR dispatch Closes gh-22989 --- .../web/filter/OncePerRequestFilter.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java b/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java index cb1b20890f7..a21fc747948 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/OncePerRequestFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package org.springframework.web.filter; import java.io.IOException; +import javax.servlet.DispatcherType; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; @@ -93,6 +94,7 @@ 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)) { @@ -165,6 +167,21 @@ 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.