Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Wilkins2013-10-24 04:30:35 +0000
committerGreg Wilkins2013-10-24 04:33:08 +0000
commitac3787b16729725b992eb0bc4b56b5cccc5d4f77 (patch)
treedee80b187951588a9f362182d57a20b7e4ed3565
parentd38233c52d256143b13db8076b4c748d9d46c4e2 (diff)
downloadorg.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
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannel.java13
-rw-r--r--jetty-server/src/main/java/org/eclipse/jetty/server/HttpChannelState.java7
-rw-r--r--jetty-servlet/src/test/java/org/eclipse/jetty/servlet/AsyncContextTest.java76
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;

Back to the top