Separate "filtered" attribute for ERROR dispatch

Resolves: #1308
See: spring-projects/spring-framework#22989
This commit is contained in:
Vedran Pavic
2019-06-10 08:23:38 +02:00
parent 3475043bf0
commit be58c00838

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2016 the original author or authors. * Copyright 2014-2019 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.springframework.session.web.http;
import java.io.IOException; import java.io.IOException;
import javax.servlet.DispatcherType;
import javax.servlet.Filter; import javax.servlet.Filter;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.FilterConfig; import javax.servlet.FilterConfig;
@@ -66,8 +67,11 @@ abstract class OncePerRequestFilter implements Filter {
} }
HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response; HttpServletResponse httpResponse = (HttpServletResponse) response;
String alreadyFilteredAttributeName = this.alreadyFilteredAttributeName;
alreadyFilteredAttributeName = updateForErrorDispatch(
alreadyFilteredAttributeName, request);
boolean hasAlreadyFilteredAttribute = request boolean hasAlreadyFilteredAttribute = request
.getAttribute(this.alreadyFilteredAttributeName) != null; .getAttribute(alreadyFilteredAttributeName) != null;
if (hasAlreadyFilteredAttribute) { if (hasAlreadyFilteredAttribute) {
@@ -76,17 +80,28 @@ abstract class OncePerRequestFilter implements Filter {
} }
else { else {
// Do invoke this filter... // Do invoke this filter...
request.setAttribute(this.alreadyFilteredAttributeName, Boolean.TRUE); request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
try { try {
doFilterInternal(httpRequest, httpResponse, filterChain); doFilterInternal(httpRequest, httpResponse, filterChain);
} }
finally { finally {
// Remove the "already filtered" request attribute for this request. // Remove the "already filtered" request attribute for this request.
request.removeAttribute(this.alreadyFilteredAttributeName); request.removeAttribute(alreadyFilteredAttributeName);
} }
} }
} }
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())
&& request.getAttribute(alreadyFilteredAttributeName) != null) {
return alreadyFilteredAttributeName + ".ERROR";
}
return alreadyFilteredAttributeName;
}
/** /**
* Same contract as for {@code doFilter}, but guaranteed to be just invoked once per * Same contract as for {@code doFilter}, but guaranteed to be just invoked once per
* request within a single request thread. * request within a single request thread.