Merge remote-tracking branch 'origin/master' into jetty-9.1
Conflicts: jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java
This commit is contained in:
commit
8bda67b82d
|
@ -35,7 +35,7 @@ public class AsyncContextEvent extends AsyncEvent
|
|||
final private AsyncContextState _asyncContext;
|
||||
volatile HttpChannelState _state;
|
||||
private ServletContext _dispatchContext;
|
||||
private String _pathInContext;
|
||||
private String _dispatchPath;
|
||||
private Scheduler.Task _timeoutTask;
|
||||
private Throwable _throwable;
|
||||
|
||||
|
@ -98,7 +98,7 @@ public class AsyncContextEvent extends AsyncEvent
|
|||
*/
|
||||
public String getPath()
|
||||
{
|
||||
return _pathInContext;
|
||||
return _dispatchPath;
|
||||
}
|
||||
|
||||
public void setTimeoutTask(Scheduler.Task task)
|
||||
|
@ -131,14 +131,15 @@ public class AsyncContextEvent extends AsyncEvent
|
|||
_throwable=throwable;
|
||||
}
|
||||
|
||||
public void setDispatchTarget(ServletContext context, String path)
|
||||
public void setDispatchContext(ServletContext context)
|
||||
{
|
||||
if (context!=null)
|
||||
_dispatchContext=context;
|
||||
if (path!=null)
|
||||
_pathInContext=path;
|
||||
_dispatchContext=context;
|
||||
}
|
||||
|
||||
public void setDispatchPath(String path)
|
||||
{
|
||||
_dispatchPath=path;
|
||||
}
|
||||
|
||||
public void completed()
|
||||
{
|
||||
|
|
|
@ -262,6 +262,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
|
|||
HttpChannelState.Action action = _state.handling();
|
||||
loop: while (action.ordinal()<HttpChannelState.Action.WAIT.ordinal() && getServer().isRunning())
|
||||
{
|
||||
boolean error=false;
|
||||
try
|
||||
{
|
||||
LOG.debug("{} action {}",this,action);
|
||||
|
@ -309,7 +310,7 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
|
|||
{
|
||||
String error_page=((ErrorHandler.ErrorPageMapper)eh).getErrorPage((HttpServletRequest)_state.getAsyncContextEvent().getSuppliedRequest());
|
||||
if (error_page!=null)
|
||||
_state.getAsyncContextEvent().setDispatchTarget(_state.getContextHandler().getServletContext(),error_page);
|
||||
_state.getAsyncContextEvent().setDispatchPath(error_page);
|
||||
}
|
||||
|
||||
getServer().handleAsync(this);
|
||||
|
@ -346,10 +347,14 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
|
|||
if ("ContinuationThrowable".equals(e.getClass().getSimpleName()))
|
||||
LOG.ignore(e);
|
||||
else
|
||||
{
|
||||
error=true;
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
error=true;
|
||||
if (e instanceof EofException)
|
||||
LOG.debug(e);
|
||||
else
|
||||
|
@ -360,6 +365,8 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
|
|||
}
|
||||
finally
|
||||
{
|
||||
if (error && _state.isAsyncStarted())
|
||||
_state.errorComplete();
|
||||
action = _state.unhandle();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -351,7 +351,11 @@ public class HttpChannelState
|
|||
if (_async!=Async.STARTED && _async!=Async.EXPIRING)
|
||||
throw new IllegalStateException("AsyncContext#dispath "+this.getStatusString());
|
||||
_async=Async.DISPATCH;
|
||||
_event.setDispatchTarget(context,path);
|
||||
|
||||
if (context!=null)
|
||||
_event.setDispatchContext(context);
|
||||
if (path!=null)
|
||||
_event.setDispatchPath(path);
|
||||
|
||||
switch(_state)
|
||||
{
|
||||
|
@ -439,6 +443,18 @@ public class HttpChannelState
|
|||
}
|
||||
}
|
||||
|
||||
public void errorComplete()
|
||||
{
|
||||
synchronized (this)
|
||||
{
|
||||
_async=Async.COMPLETE;
|
||||
_event.setDispatchContext(null);
|
||||
_event.setDispatchPath(null);
|
||||
}
|
||||
|
||||
cancelTimeout();
|
||||
}
|
||||
|
||||
protected void completed()
|
||||
{
|
||||
final List<AsyncListener> aListeners;
|
||||
|
|
|
@ -2044,7 +2044,8 @@ public class Request implements HttpServletRequest
|
|||
if (_async==null)
|
||||
_async=new AsyncContextState(state);
|
||||
AsyncContextEvent event = new AsyncContextEvent(_context,_async,state,this,servletRequest,servletResponse);
|
||||
event.setDispatchTarget(getServletContext(),URIUtil.addPaths(getServletPath(),getPathInfo()));
|
||||
event.setDispatchContext(getServletContext());
|
||||
event.setDispatchPath(URIUtil.addPaths(getServletPath(),getPathInfo()));
|
||||
state.startAsync(event);
|
||||
return _async;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ import org.eclipse.jetty.server.Request;
|
|||
* Can be applied in jetty.xml with
|
||||
* <pre>
|
||||
* <Get id='handler' name='Handler'/>
|
||||
* <Set name='Handler>
|
||||
* <Set name='Handler'>
|
||||
* <New id='idleTimeoutHandler' class='org.eclipse.jetty.server.handler.IdleTimeoutHandler'>
|
||||
* <Set name='Handler'><Ref id='handler'/></Set>
|
||||
* <Set name='IdleTimeoutMs'>5000</Set>
|
||||
|
|
|
@ -613,7 +613,7 @@ public class ServletHandler extends ScopedHandler
|
|||
{
|
||||
// Complete async errored requests
|
||||
if (th!=null && request.isAsyncStarted())
|
||||
request.getAsyncContext().complete();
|
||||
baseRequest.getHttpChannelState().errorComplete();
|
||||
|
||||
if (servlet_holder!=null)
|
||||
baseRequest.setHandled(true);
|
||||
|
|
|
@ -122,8 +122,11 @@ public class AsyncContextTest
|
|||
@Test
|
||||
public void testStartThrow() throws Exception
|
||||
{
|
||||
String request = "GET /ctx/startthrow HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
|
||||
+ "Connection: close\r\n" + "\r\n";
|
||||
String request =
|
||||
"GET /ctx/startthrow HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
String responseString = _connector.getResponses(request);
|
||||
|
||||
BufferedReader br = new BufferedReader(new StringReader(responseString));
|
||||
|
@ -138,6 +141,68 @@ public class AsyncContextTest
|
|||
Assert.assertEquals("error servlet","EXCEPTION: org.eclipse.jetty.server.QuietServletException: java.io.IOException: Test",br.readLine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartDispatchThrow() throws Exception
|
||||
{
|
||||
String request = "GET /ctx/startthrow?dispatch=true HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Content-Type: application/x-www-form-urlencoded\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
String responseString = _connector.getResponses(request);
|
||||
|
||||
BufferedReader br = new BufferedReader(new StringReader(responseString));
|
||||
|
||||
assertEquals("HTTP/1.1 500 Server Error",br.readLine());
|
||||
br.readLine();// connection close
|
||||
br.readLine();// server
|
||||
br.readLine();// empty
|
||||
Assert.assertEquals("error servlet","ERROR: /error",br.readLine());
|
||||
Assert.assertEquals("error servlet","PathInfo= /IOE",br.readLine());
|
||||
Assert.assertEquals("error servlet","EXCEPTION: org.eclipse.jetty.server.QuietServletException: java.io.IOException: Test",br.readLine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartCompleteThrow() throws Exception
|
||||
{
|
||||
String request = "GET /ctx/startthrow?complete=true HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Content-Type: application/x-www-form-urlencoded\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
String responseString = _connector.getResponses(request);
|
||||
|
||||
BufferedReader br = new BufferedReader(new StringReader(responseString));
|
||||
|
||||
assertEquals("HTTP/1.1 500 Server Error",br.readLine());
|
||||
br.readLine();// connection close
|
||||
br.readLine();// server
|
||||
br.readLine();// empty
|
||||
Assert.assertEquals("error servlet","ERROR: /error",br.readLine());
|
||||
Assert.assertEquals("error servlet","PathInfo= /IOE",br.readLine());
|
||||
Assert.assertEquals("error servlet","EXCEPTION: org.eclipse.jetty.server.QuietServletException: java.io.IOException: Test",br.readLine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartFlushCompleteThrow() throws Exception
|
||||
{
|
||||
String request = "GET /ctx/startthrow?flush=true&complete=true HTTP/1.1\r\n" +
|
||||
"Host: localhost\r\n" +
|
||||
"Content-Type: application/x-www-form-urlencoded\r\n" +
|
||||
"Connection: close\r\n" +
|
||||
"\r\n";
|
||||
String responseString = _connector.getResponses(request);
|
||||
|
||||
BufferedReader br = new BufferedReader(new StringReader(responseString));
|
||||
|
||||
assertEquals("HTTP/1.1 200 OK",br.readLine());
|
||||
br.readLine();// connection close
|
||||
br.readLine();// server
|
||||
br.readLine();// empty
|
||||
|
||||
Assert.assertEquals("error servlet","completeBeforeThrow",br.readLine());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDispatchAsyncContext() throws Exception
|
||||
{
|
||||
|
@ -497,6 +562,20 @@ public class AsyncContextTest
|
|||
if (request.getDispatcherType()==DispatcherType.REQUEST)
|
||||
{
|
||||
request.startAsync(request, response);
|
||||
|
||||
if (Boolean.valueOf(request.getParameter("dispatch")))
|
||||
{
|
||||
request.getAsyncContext().dispatch();
|
||||
}
|
||||
|
||||
if (Boolean.valueOf(request.getParameter("complete")))
|
||||
{
|
||||
response.getOutputStream().write("completeBeforeThrow".getBytes());
|
||||
if (Boolean.valueOf(request.getParameter("flush")))
|
||||
response.flushBuffer();
|
||||
request.getAsyncContext().complete();
|
||||
}
|
||||
|
||||
throw new QuietServletException(new IOException("Test"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -322,6 +322,17 @@ public class QueuedThreadPool extends AbstractLifeCycle implements SizedThreadPo
|
|||
return _priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of the job queue.
|
||||
*
|
||||
* @return Number of jobs queued waiting for a thread
|
||||
*/
|
||||
@ManagedAttribute("Size of the job queue")
|
||||
public int getQueueSize()
|
||||
{
|
||||
return _jobs.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegated to the named or anonymous Pool.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue