371635: set all async attributes when the request is suspended

This commit is contained in:
Greg Wilkins 2012-02-27 16:32:50 +11:00
parent f87cd6d1ba
commit 7a58f3408e
5 changed files with 51 additions and 55 deletions

View File

@ -309,7 +309,7 @@ public class AsyncContinuation implements AsyncContext, Continuation
else
{
_event._dispatchContext=null;
_event._path=null;
_event._pathInContext=null;
}
_state=__ASYNCSTARTED;
@ -710,14 +710,14 @@ public class AsyncContinuation implements AsyncContext, Continuation
public void dispatch(ServletContext context, String path)
{
_event._dispatchContext=context;
_event._path=path;
_event._pathInContext=path;
dispatch();
}
/* ------------------------------------------------------------ */
public void dispatch(String path)
{
_event._path=path;
_event._pathInContext=path;
dispatch();
}
@ -892,13 +892,43 @@ public class AsyncContinuation implements AsyncContext, Continuation
private final ServletRequest _request;
private final ServletResponse _response;
private ServletContext _dispatchContext;
private String _path;
private String _pathInContext;
public AsyncEventState(ServletContext context, ServletRequest request, ServletResponse response)
{
_suspendedContext=context;
_request=request;
_response=response;
// Get the base request So we can remember the initial paths
Request r=_connection.getRequest();
// If we haven't been async dispatched before
if (r.getAttribute(AsyncContext.ASYNC_REQUEST_URI)==null)
{
// We are setting these attributes during startAsync, when the spec implies that
// they are only available after a call to AsyncContext.dispatch(...);
// have we been forwarded before?
String uri=(String)r.getAttribute(Dispatcher.FORWARD_REQUEST_URI);
if (uri!=null)
{
r.setAttribute(AsyncContext.ASYNC_REQUEST_URI,uri);
r.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,(String)r.getAttribute(Dispatcher.FORWARD_CONTEXT_PATH));
r.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,(String)r.getAttribute(Dispatcher.FORWARD_SERVLET_PATH));
r.setAttribute(AsyncContext.ASYNC_PATH_INFO,(String)r.getAttribute(Dispatcher.FORWARD_PATH_INFO));
r.setAttribute(AsyncContext.ASYNC_QUERY_STRING,(String)r.getAttribute(Dispatcher.FORWARD_QUERY_STRING));
}
else
{
r.setAttribute(AsyncContext.ASYNC_REQUEST_URI,r.getRequestURI());
r.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,r.getContextPath());
r.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,r.getServletPath());
r.setAttribute(AsyncContext.ASYNC_PATH_INFO,r.getPathInfo());
r.setAttribute(AsyncContext.ASYNC_QUERY_STRING,r.getQueryString());
}
}
}
public ServletContext getSuspendedContext()
@ -926,9 +956,13 @@ public class AsyncContinuation implements AsyncContext, Continuation
return _response;
}
/* ------------------------------------------------------------ */
/**
* @return The path in the context
*/
public String getPath()
{
return _path;
return _pathInContext;
}
@Override

View File

@ -366,14 +366,6 @@ public class Server extends HandlerWrapper implements Attributes
if (path!=null)
{
// this is a dispatch with a path
baseRequest.setAttribute(AsyncContext.ASYNC_REQUEST_URI,baseRequest.getRequestURI());
baseRequest.setAttribute(AsyncContext.ASYNC_QUERY_STRING,baseRequest.getQueryString());
baseRequest.setAttribute(AsyncContext.ASYNC_CONTEXT_PATH,state.getSuspendedContext().getContextPath());
// Part of #371649 reset here since we skip it in finally
baseRequest.setServletPath(null);
final String contextPath=state.getServletContext().getContextPath();
HttpURI uri = new HttpURI(URIUtil.addPaths(contextPath,path));
baseRequest.setUri(uri);

View File

@ -971,7 +971,6 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
}
finally
{
if (old_context != _scontext)
{
// reset the classloader
@ -984,13 +983,8 @@ public class ContextHandler extends ScopedHandler implements Attributes, Server.
baseRequest.setContext(old_context);
__context.set(old_context);
baseRequest.setContextPath(old_context_path);
// #371649 if we have started async then we need to protect this state
if (!baseRequest.getAsyncContinuation().isAsyncStarted())
{
baseRequest.setServletPath(old_servlet_path);
baseRequest.setPathInfo(old_path_info);
}
baseRequest.setServletPath(old_servlet_path);
baseRequest.setPathInfo(old_path_info);
}
}
}

View File

@ -45,7 +45,6 @@ import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.security.IdentityService;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.server.AbstractHttpConnection;
import org.eclipse.jetty.server.AsyncContext;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.DispatcherType;
import org.eclipse.jetty.server.Request;
@ -352,7 +351,7 @@ public class ServletHandler extends ScopedHandler
// Get the base requests
final String old_servlet_path=baseRequest.getServletPath();
final String old_path_info=baseRequest.getPathInfo();
DispatcherType type = baseRequest.getDispatcherType();
ServletHolder servlet_holder=null;
@ -377,7 +376,7 @@ public class ServletHandler extends ScopedHandler
baseRequest.setAttribute(Dispatcher.INCLUDE_PATH_INFO, path_info);
}
else
{
{
baseRequest.setServletPath(servlet_path);
baseRequest.setPathInfo(path_info);
}
@ -398,21 +397,6 @@ public class ServletHandler extends ScopedHandler
old_scope=baseRequest.getUserIdentityScope();
baseRequest.setUserIdentityScope(servlet_holder);
/*
* this is an interim solution for Bug 371635
*
* these will always be set now, when they ought to only be set on the dispatch
*/
if ( baseRequest.getAttribute(AsyncContext.ASYNC_SERVLET_PATH) == null )
{
baseRequest.setAttribute(AsyncContext.ASYNC_SERVLET_PATH,baseRequest.getServletPath());
}
if ( baseRequest.getAttribute(AsyncContext.ASYNC_PATH_INFO) == null )
{
baseRequest.setAttribute(AsyncContext.ASYNC_PATH_INFO,baseRequest.getPathInfo());
}
// start manual inline of nextScope(target,baseRequest,request,response);
if (never())
nextScope(target,baseRequest,request,response);
@ -426,18 +410,13 @@ public class ServletHandler extends ScopedHandler
}
finally
{
// #371649 if we have started async then we need to protect this state
if (!baseRequest.getAsyncContinuation().isAsyncStarted())
if (old_scope!=null)
baseRequest.setUserIdentityScope(old_scope);
if (!(DispatcherType.INCLUDE.equals(type)))
{
if (old_scope != null)
baseRequest.setUserIdentityScope(old_scope);
if (!(DispatcherType.INCLUDE.equals(type)))
{
baseRequest.setServletPath(old_servlet_path);
baseRequest.setPathInfo(old_path_info);
}
baseRequest.setServletPath(old_servlet_path);
baseRequest.setPathInfo(old_path_info);
}
}
}

View File

@ -74,7 +74,7 @@ public class AsyncContextTest
Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath", br.readLine());
Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath", br.readLine());
Assert.assertEquals("async context gets right path in async","async:run:/servletPath", br.readLine());
Assert.assertEquals("async context gets right path in async","async:run:attr:servletPath:/servletPath", br.readLine());
}
@Test
@ -95,7 +95,6 @@ public class AsyncContextTest
Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath2", br.readLine());
Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath2", br.readLine());
Assert.assertEquals("async context gets right path in async","async:run:/servletPath2", br.readLine());
Assert.assertEquals("servlet path attr is original","async:run:attr:servletPath:/servletPath", br.readLine());
Assert.assertEquals("path info attr is correct","async:run:attr:pathInfo:null", br.readLine());
Assert.assertEquals("query string attr is correct","async:run:attr:queryString:dispatch=true", br.readLine());
@ -123,7 +122,7 @@ public class AsyncContextTest
Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath", br.readLine());
Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath", br.readLine());
Assert.assertEquals("async context gets right path in async","async:run:/servletPath", br.readLine());
Assert.assertEquals("async context gets right path in async","async:run:attr:servletPath:/servletPath", br.readLine());
}
@Test
@ -148,7 +147,6 @@ public class AsyncContextTest
Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath2", br.readLine());
Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath2", br.readLine());
Assert.assertEquals("async context gets right path in async","async:run:/servletPath2", br.readLine());
Assert.assertEquals("servlet path attr is original","async:run:attr:servletPath:/servletPath", br.readLine());
Assert.assertEquals("path info attr is correct","async:run:attr:pathInfo:null", br.readLine());
Assert.assertEquals("query string attr is correct","async:run:attr:queryString:dispatch=true", br.readLine());
@ -234,7 +232,6 @@ public class AsyncContextTest
try
{
_continuation.getResponse().getOutputStream().print("async:run:" + req.getServletPath() + "\n");
_continuation.getResponse().getOutputStream().print("async:run:attr:servletPath:" + req.getAttribute(AsyncContext.ASYNC_SERVLET_PATH) + "\n");
_continuation.getResponse().getOutputStream().print("async:run:attr:pathInfo:" + req.getAttribute(AsyncContext.ASYNC_PATH_INFO) + "\n");
_continuation.getResponse().getOutputStream().print("async:run:attr:queryString:" + req.getAttribute(AsyncContext.ASYNC_QUERY_STRING) + "\n");