420033 AsyncContext.onTimeout exceptions passed to onError
Conflicts: jetty-server/src/main/java/org/eclipse/jetty/server/AbstractHttpConnection.java jetty-server/src/main/java/org/eclipse/jetty/server/AsyncContinuation.java jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java
This commit is contained in:
parent
d38233c52d
commit
ac3787b167
|
@ -274,10 +274,19 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable
|
||||||
if (_request.getHttpChannelState().isExpired())
|
if (_request.getHttpChannelState().isExpired())
|
||||||
{
|
{
|
||||||
_request.setDispatcherType(DispatcherType.ERROR);
|
_request.setDispatcherType(DispatcherType.ERROR);
|
||||||
|
|
||||||
|
Throwable ex=_state.getAsyncContextEvent().getThrowable();
|
||||||
|
String reason="Async Timeout";
|
||||||
|
if (ex!=null)
|
||||||
|
{
|
||||||
|
reason="Async Exception";
|
||||||
|
_request.setAttribute(RequestDispatcher.ERROR_EXCEPTION,ex);
|
||||||
|
}
|
||||||
_request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(500));
|
_request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE,new Integer(500));
|
||||||
_request.setAttribute(RequestDispatcher.ERROR_MESSAGE,"Async Timeout");
|
_request.setAttribute(RequestDispatcher.ERROR_MESSAGE,reason);
|
||||||
_request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI,_request.getRequestURI());
|
_request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI,_request.getRequestURI());
|
||||||
_response.setStatusWithReason(500,"Async Timeout");
|
|
||||||
|
_response.setStatusWithReason(500,reason);
|
||||||
|
|
||||||
ErrorHandler eh = _state.getContextHandler().getErrorHandler();
|
ErrorHandler eh = _state.getContextHandler().getErrorHandler();
|
||||||
if (eh instanceof ErrorHandler.ErrorPageMapper)
|
if (eh instanceof ErrorHandler.ErrorPageMapper)
|
||||||
|
|
|
@ -348,7 +348,7 @@ public class HttpChannelState
|
||||||
protected void expired()
|
protected void expired()
|
||||||
{
|
{
|
||||||
final List<AsyncListener> aListeners;
|
final List<AsyncListener> aListeners;
|
||||||
AsyncEvent event;
|
AsyncContextEvent event;
|
||||||
synchronized (this)
|
synchronized (this)
|
||||||
{
|
{
|
||||||
switch(_state)
|
switch(_state)
|
||||||
|
@ -374,7 +374,10 @@ public class HttpChannelState
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
LOG.warn(e);
|
LOG.debug(e);
|
||||||
|
event.setThrowable(e);
|
||||||
|
_channel.getRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,e);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,10 @@ import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
|
||||||
import javax.servlet.AsyncContext;
|
import javax.servlet.AsyncContext;
|
||||||
|
import javax.servlet.AsyncEvent;
|
||||||
|
import javax.servlet.AsyncListener;
|
||||||
import javax.servlet.DispatcherType;
|
import javax.servlet.DispatcherType;
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -76,6 +79,7 @@ public class AsyncContextTest
|
||||||
_contextHandler.addServlet(new ServletHolder(new ForwardingServlet()),"/forward");
|
_contextHandler.addServlet(new ServletHolder(new ForwardingServlet()),"/forward");
|
||||||
_contextHandler.addServlet(new ServletHolder(new AsyncDispatchingServlet()),"/dispatchingServlet");
|
_contextHandler.addServlet(new ServletHolder(new AsyncDispatchingServlet()),"/dispatchingServlet");
|
||||||
_contextHandler.addServlet(new ServletHolder(new ExpireServlet()),"/expire/*");
|
_contextHandler.addServlet(new ServletHolder(new ExpireServlet()),"/expire/*");
|
||||||
|
_contextHandler.addServlet(new ServletHolder(new BadExpireServlet()),"/badexpire/*");
|
||||||
_contextHandler.addServlet(new ServletHolder(new ErrorServlet()),"/error/*");
|
_contextHandler.addServlet(new ServletHolder(new ErrorServlet()),"/error/*");
|
||||||
|
|
||||||
ErrorPageErrorHandler error_handler = new ErrorPageErrorHandler();
|
ErrorPageErrorHandler error_handler = new ErrorPageErrorHandler();
|
||||||
|
@ -287,8 +291,11 @@ public class AsyncContextTest
|
||||||
@Test
|
@Test
|
||||||
public void testExpire() throws Exception
|
public void testExpire() throws Exception
|
||||||
{
|
{
|
||||||
String request = "GET /ctx/expire HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
|
String request = "GET /ctx/expire HTTP/1.1\r\n" +
|
||||||
+ "Connection: close\r\n" + "\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);
|
String responseString = _connector.getResponses(request);
|
||||||
|
|
||||||
BufferedReader br = new BufferedReader(new StringReader(responseString));
|
BufferedReader br = new BufferedReader(new StringReader(responseString));
|
||||||
|
@ -299,7 +306,28 @@ public class AsyncContextTest
|
||||||
br.readLine();// server
|
br.readLine();// server
|
||||||
br.readLine();// empty
|
br.readLine();// empty
|
||||||
|
|
||||||
Assert.assertEquals("error servlet","ERROR:/error",br.readLine());
|
Assert.assertEquals("error servlet","ERROR: /error",br.readLine());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBadExpire() throws Exception
|
||||||
|
{
|
||||||
|
String request = "GET /ctx/badexpire 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 Async Exception",br.readLine());
|
||||||
|
br.readLine();// connection close
|
||||||
|
br.readLine();// server
|
||||||
|
br.readLine();// empty
|
||||||
|
|
||||||
|
Assert.assertEquals("error servlet","ERROR: /error",br.readLine());
|
||||||
|
Assert.assertEquals("error servlet","EXCEPTION: java.io.IOException: TEST",br.readLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DispatchingRunnable implements Runnable
|
private class DispatchingRunnable implements Runnable
|
||||||
|
@ -336,7 +364,9 @@ public class AsyncContextTest
|
||||||
@Override
|
@Override
|
||||||
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
{
|
{
|
||||||
response.getOutputStream().print("ERROR:" + request.getServletPath() + "\n");
|
response.getOutputStream().print("ERROR: " + request.getServletPath() + "\n");
|
||||||
|
if (request.getAttribute(RequestDispatcher.ERROR_EXCEPTION)!=null)
|
||||||
|
response.getOutputStream().print("EXCEPTION: " + request.getAttribute(RequestDispatcher.ERROR_EXCEPTION) + "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,6 +385,44 @@ public class AsyncContextTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class BadExpireServlet extends HttpServlet
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
|
||||||
|
{
|
||||||
|
if (request.getDispatcherType()==DispatcherType.REQUEST)
|
||||||
|
{
|
||||||
|
AsyncContext asyncContext = request.startAsync();
|
||||||
|
asyncContext.addListener(new AsyncListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onTimeout(AsyncEvent event) throws IOException
|
||||||
|
{
|
||||||
|
throw new IOException("TEST");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartAsync(AsyncEvent event) throws IOException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(AsyncEvent event) throws IOException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete(AsyncEvent event) throws IOException
|
||||||
|
{
|
||||||
|
}
|
||||||
|
});
|
||||||
|
asyncContext.setTimeout(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class TestServlet extends HttpServlet
|
private class TestServlet extends HttpServlet
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
Loading…
Reference in New Issue