Commit Session on Include Dispatch

The servlet spec disallows any writing of headers after an include has been issued.

This commit intercepts the include and commits the session, then
allowing the include to proceed.

See: #1243
This commit is contained in:
Josh Cummings
2018-11-02 21:18:53 +01:00
committed by Vedran Pavic
parent 11ad1db6e7
commit c8f3d1a1ec
2 changed files with 43 additions and 0 deletions

View File

@@ -21,8 +21,11 @@ import java.time.Instant;
import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
@@ -358,6 +361,12 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
return this.requestedSessionId;
}
@Override
public RequestDispatcher getRequestDispatcher(String path) {
RequestDispatcher requestDispatcher = super.getRequestDispatcher(path);
return new SessionCommittingRequestDispatcher(requestDispatcher);
}
private S getRequestedSession() {
if (!this.requestedSessionCached) {
List<String> sessionIds = SessionRepositoryFilter.this.httpSessionIdResolver
@@ -407,6 +416,25 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
}
}
private final class SessionCommittingRequestDispatcher implements RequestDispatcher {
private final RequestDispatcher delegate;
SessionCommittingRequestDispatcher(RequestDispatcher delegate) {
this.delegate = delegate;
}
@Override
public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
this.delegate.forward(request, response);
}
@Override
public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException {
SessionRepositoryRequestWrapper.this.commitSession();
this.delegate.include(request, response);
}
}
}
}

View File

@@ -1170,6 +1170,21 @@ public class SessionRepositoryFilterTests {
});
}
@Test
public void doFilterInclude() throws Exception {
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest,
HttpServletResponse wrappedResponse) throws IOException, ServletException {
String id = wrappedRequest.getSession().getId();
wrappedRequest.getRequestDispatcher("/").include(wrappedRequest, wrappedResponse);
assertThat(
SessionRepositoryFilterTests.this.sessionRepository.findById(id))
.isNotNull();
}
});
}
// --- HttpSessionIdResolver
@Test