Author: markt
Date: Thu Aug 1 09:46:15 2013
New Revision: 1509151
URL: http://svn.apache.org/r1509151
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=55331
A disatch to an async servlet during the onTimeout method of an async listener
should not trigger an ISE.
Modified:
tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java
tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
Modified: tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java?rev=1509151&r1=1509150&r2=1509151&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java (original)
+++ tomcat/trunk/java/org/apache/coyote/AsyncStateMachine.java Thu Aug 1
09:46:15 2013
@@ -216,6 +216,10 @@ public class AsyncStateMachine<S> {
} else if (state == AsyncState.DISPATCHING) {
state = AsyncState.DISPATCHED;
return SocketState.ASYNC_END;
+ } else if (state == AsyncState.STARTED) {
+ // This can occur if an async listener does a dispatch to an async
+ // servlet during onTimeout
+ return SocketState.LONG;
} else {
throw new IllegalStateException(
sm.getString("asyncStateMachine.invalidAsyncState",
Modified: tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java?rev=1509151&r1=1509150&r2=1509151&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
(original)
+++ tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java Thu
Aug 1 09:46:15 2013
@@ -46,8 +46,6 @@ import javax.servlet.http.HttpServletRes
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
import org.junit.Assert;
import org.junit.Test;
@@ -398,18 +396,31 @@ public class TestAsyncContextImpl extend
}
@Test
- public void testTimeoutListenerCompleteDispatch() throws Exception {
+ public void testTimeoutListenerCompleteNonAsyncDispatch() throws Exception
{
// Should trigger an error - can't do both
doTestTimeout(Boolean.TRUE, Boolean.FALSE);
}
@Test
- public void testTimeoutListenerNoCompleteDispatch() throws Exception {
+ public void testTimeoutListenerNoCompleteNonAsyncDispatch()
+ throws Exception {
// Should work
doTestTimeout(Boolean.FALSE, Boolean.FALSE);
}
@Test
+ public void testTimeoutListenerCompleteAsyncDispatch() throws Exception {
+ // Should trigger an error - can't do both
+ doTestTimeout(Boolean.TRUE, Boolean.TRUE);
+ }
+
+ @Test
+ public void testTimeoutListenerNoCompleteAsyncDispatch() throws Exception {
+ // Should work
+ doTestTimeout(Boolean.FALSE, Boolean.TRUE);
+ }
+
+ @Test
public void testTimeoutNoListener() throws Exception {
// Should work
doTestTimeout(null, null);
@@ -433,13 +444,6 @@ public class TestAsyncContextImpl extend
// Must have a real docBase - just use temp
File docBase = new File(System.getProperty("java.io.tmpdir"));
- // Create the folder that will trigger the redirect
- File foo = new File(docBase, "async");
- addDeleteOnTearDown(foo);
- if (!foo.mkdirs() && !foo.isDirectory()) {
- fail("Unable to create async directory in docBase");
- }
-
Context ctx = tomcat.addContext("", docBase.getAbsolutePath());
TimeoutServlet timeout =
@@ -451,8 +455,11 @@ public class TestAsyncContextImpl extend
if (asyncDispatch != null) {
if (asyncDispatch.booleanValue()) {
- AsyncStartRunnable asyncStartRunnable = new
AsyncStartRunnable();
- Tomcat.addServlet(ctx, "async", asyncStartRunnable);
+ AsyncStartRunnable asyncStartRunnable =
+ new AsyncStartRunnable();
+ Wrapper async =
+ Tomcat.addServlet(ctx, "async", asyncStartRunnable);
+ async.setAsyncSupported(true);
ctx.addServletMapping(dispatchUrl, "async");
} else {
NonAsyncServlet nonAsync = new NonAsyncServlet();
@@ -488,7 +495,7 @@ public class TestAsyncContextImpl extend
expected.append("onTimeout-");
if (asyncDispatch != null) {
if (asyncDispatch.booleanValue()) {
- // TODO
+ expected.append("onStartAsync-Runnable-");
} else {
expected.append("NonAsyncServletGet-");
}
@@ -507,12 +514,16 @@ public class TestAsyncContextImpl extend
TimeoutServlet.ASYNC_TIMEOUT + TIMEOUT_MARGIN +
REQUEST_TIME);
} else {
- alvGlobal.validateAccessLog(1, 200, TimeoutServlet.ASYNC_TIMEOUT,
- TimeoutServlet.ASYNC_TIMEOUT + TIMEOUT_MARGIN +
- REQUEST_TIME);
- alv.validateAccessLog(1, 200, TimeoutServlet.ASYNC_TIMEOUT,
- TimeoutServlet.ASYNC_TIMEOUT + TIMEOUT_MARGIN +
- REQUEST_TIME);
+ long timeoutDelay = TimeoutServlet.ASYNC_TIMEOUT;
+ if (asyncDispatch != null && asyncDispatch.booleanValue() &&
+ !completeOnTimeout.booleanValue()) {
+ // Extra timeout in this case
+ timeoutDelay += TimeoutServlet.ASYNC_TIMEOUT;
+ }
+ alvGlobal.validateAccessLog(1, 200, timeoutDelay,
+ timeoutDelay + TIMEOUT_MARGIN + REQUEST_TIME);
+ alv.validateAccessLog(1, 200, timeoutDelay,
+ timeoutDelay + TIMEOUT_MARGIN + REQUEST_TIME);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]