diff options
author | Greg Wilkins | 2013-10-24 04:30:35 +0000 |
---|---|---|
committer | Greg Wilkins | 2013-10-24 04:33:08 +0000 |
commit | ac3787b16729725b992eb0bc4b56b5cccc5d4f77 (patch) | |
tree | dee80b187951588a9f362182d57a20b7e4ed3565 | |
parent | d38233c52d256143b13db8076b4c748d9d46c4e2 (diff) | |
download | org.eclipse.jetty.project-ac3787b16729725b992eb0bc4b56b5cccc5d4f77.tar.gz org.eclipse.jetty.project-ac3787b16729725b992eb0bc4b56b5cccc5d4f77.tar.xz org.eclipse.jetty.project-ac3787b16729725b992eb0bc4b56b5cccc5d4f77.zip |
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
3 files changed, 88 insertions, 8 deletions
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java index 4a13d7e3a4..4c2bd54bbf 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java @@ -274,10 +274,19 @@ public class HttpChannel<T> implements HttpParser.RequestHandler<T>, Runnable if (_request.getHttpChannelState().isExpired()) { _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_MESSAGE,"Async Timeout"); + _request.setAttribute(RequestDispatcher.ERROR_MESSAGE,reason); _request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI,_request.getRequestURI()); - _response.setStatusWithReason(500,"Async Timeout"); + + _response.setStatusWithReason(500,reason); ErrorHandler eh = _state.getContextHandler().getErrorHandler(); if (eh instanceof ErrorHandler.ErrorPageMapper) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java index 127bafa3c1..99c17172bb 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java @@ -348,7 +348,7 @@ public class HttpChannelState protected void expired() { final List<AsyncListener> aListeners; - AsyncEvent event; + AsyncContextEvent event; synchronized (this) { switch(_state) @@ -374,7 +374,10 @@ public class HttpChannelState } catch(Exception e) { - LOG.warn(e); + LOG.debug(e); + event.setThrowable(e); + _channel.getRequest().setAttribute(RequestDispatcher.ERROR_EXCEPTION,e); + break; } } } diff --git a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java index ae74bf7e60..121874ce76 100644 --- a/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java +++ b/jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java @@ -28,7 +28,10 @@ import java.io.IOException; import java.io.StringReader; import javax.servlet.AsyncContext; +import javax.servlet.AsyncEvent; +import javax.servlet.AsyncListener; import javax.servlet.DispatcherType; +import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -76,6 +79,7 @@ public class AsyncContextTest _contextHandler.addServlet(new ServletHolder(new ForwardingServlet()),"/forward"); _contextHandler.addServlet(new ServletHolder(new AsyncDispatchingServlet()),"/dispatchingServlet"); _contextHandler.addServlet(new ServletHolder(new ExpireServlet()),"/expire/*"); + _contextHandler.addServlet(new ServletHolder(new BadExpireServlet()),"/badexpire/*"); _contextHandler.addServlet(new ServletHolder(new ErrorServlet()),"/error/*"); ErrorPageErrorHandler error_handler = new ErrorPageErrorHandler(); @@ -287,8 +291,11 @@ public class AsyncContextTest @Test 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" - + "Connection: close\r\n" + "\r\n"; + String request = "GET /ctx/expire 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)); @@ -299,7 +306,28 @@ public class AsyncContextTest br.readLine();// server 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 @@ -336,7 +364,9 @@ public class AsyncContextTest @Override 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 static final long serialVersionUID = 1L; |