-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
Jetty version(s)
12.0.21
Jetty Environment
ee9 / ee8 (but could be present in others too)
Description
When a cross-context dispatch occurs, and the dispatched to endpoint uses an AsyncContext.dispatch(), then the resulting dispatch has the wrong state, and dispatches to the previous context.
Example:
We have 2 contexts involved.
- Context root
/- has a Filter that performs cross-context-dispatch.
- Context service
/service- has an Servlet
/alt/*that uses AsyncContext and performs a dispatch()
- has an Servlet
The order of events.
- Context root
/receives a request. - The filter on Context root
/gets a ServletContext from/service - The filter gets a RequestDispatcher from
/serviceto a path /service/alt/` context. - The filter performs a
RequestDispatcher.forward()to this/serviceendpoint - The
/service/alt/*servlet receives the FORWARD request. - The
/service/alt/*servlet establishes an AsyncContext, waits for a timeout, and then performs adispatch() - (Where problem occurs) - this dispatch goes to the root
/context.
There are two problems observed (could be more).
First in the jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/Dispatcher.java
The call to protected void forward(ServletRequest request, ServletResponse response, DispatcherType dispatch) throws ServletException, IOException has a finally block that resets several Request settings, like the HttpURI, this results in bad HttpServletRequest.getRequestURL on the dispatch.
Next is the jetty-ee9/jetty-ee9-servlet/src/main/java/org/eclipse/jetty/ee9/servlet/ServletHandler.java
In the call to public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, there is a finally block that resets the old scope using baseRequest.setUserIdentityScope(oldScope), this sets the Context back to the original context, which results in the AsyncContext.dispatch() calling the original context, not the dispatched to context, like what is expected (and how the behavior works in Jetty 11/10/9).