Author: markt
Date: Mon Dec 15 16:15:34 2014
New Revision: 1645685
URL: http://svn.apache.org/r1645685
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=57326
Enable AsyncListeners to re-register themselves through
AsyncListener.onStartAsync ()
Modified:
tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
Modified: tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java?rev=1645685&r1=1645684&r2=1645685&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/AsyncContextImpl.java Mon Dec 15
16:15:34 2014
@@ -339,6 +339,7 @@ public class AsyncContextImpl implements
List<AsyncListenerWrapper> listenersCopy = new ArrayList<>();
listenersCopy.addAll(listeners);
+ listeners.clear();
for (AsyncListenerWrapper listener : listenersCopy) {
try {
listener.fireOnStartAsync(event);
@@ -348,7 +349,6 @@ public class AsyncContextImpl implements
listener.getClass().getName() + "]", t);
}
}
- listeners.clear();
}
@Override
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=1645685&r1=1645684&r2=1645685&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
(original)
+++ tomcat/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java Mon
Dec 15 16:15:34 2014
@@ -31,6 +31,7 @@ import javax.servlet.AsyncListener;
import javax.servlet.DispatcherType;
import javax.servlet.GenericServlet;
import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
@@ -463,8 +464,7 @@ public class TestAsyncContextImpl extend
// No file system docBase required
Context ctx = tomcat.addContext("", null);
- TimeoutServlet timeout =
- new TimeoutServlet(completeOnTimeout, dispatchUrl);
+ TimeoutServlet timeout = new TimeoutServlet(completeOnTimeout,
dispatchUrl);
Wrapper wrapper = Tomcat.addServlet(ctx, "time", timeout);
wrapper.setAsyncSupported(true);
@@ -859,6 +859,21 @@ public class TestAsyncContextImpl extend
}
}
+ private static class StickyTrackingListener extends TrackingListener {
+
+ public StickyTrackingListener(boolean completeOnError,
+ boolean completeOnTimeout, String dispatchUrl) {
+ super(completeOnError, completeOnTimeout, dispatchUrl);
+ }
+
+ @Override
+ public void onStartAsync(AsyncEvent event) throws IOException {
+ super.onStartAsync(event);
+ // Re-add this listener to the new AsyncContext
+ event.getAsyncContext().addListener(this);
+ }
+ }
+
public static class TrackingRequestListener
implements ServletRequestListener {
@@ -2066,4 +2081,67 @@ public class TestAsyncContextImpl extend
}
Assert.assertEquals(expectedTrack, getTrack());
}
+
+
+ // https://issues.apache.org/bugzilla/show_bug.cgi?id=57326
+ @Test
+ public void testAsyncContextListenerClearing() throws Exception {
+ resetTracker();
+
+ // Setup Tomcat instance
+ Tomcat tomcat = getTomcatInstance();
+
+ // No file system docBase required
+ Context ctx = tomcat.addContext("", null);
+
+ Servlet stage1 = new DispatchingServletTracking("/stage2", true);
+ Wrapper wrapper1 = Tomcat.addServlet(ctx, "stage1", stage1);
+ wrapper1.setAsyncSupported(true);
+ ctx.addServletMapping("/stage1", "stage1");
+
+ Servlet stage2 = new DispatchingServletTracking("/stage3", false);
+ Wrapper wrapper2 = Tomcat.addServlet(ctx, "stage2", stage2);
+ wrapper2.setAsyncSupported(true);
+ ctx.addServletMapping("/stage2", "stage2");
+
+ Servlet stage3 = new NonAsyncServlet();
+ Tomcat.addServlet(ctx, "stage3", stage3);
+ ctx.addServletMapping("/stage3", "stage3");
+
+ TesterAccessLogValve alv = new TesterAccessLogValve();
+ ctx.getPipeline().addValve(alv);
+
+ tomcat.start();
+
+ getUrl("http://localhost:" + getPort()+ "/stage1");
+
+
assertEquals("doGet-startAsync-doGet-startAsync-onStartAsync-NonAsyncServletGet-onComplete-",
getTrack());
+
+ // Check the access log
+ alv.validateAccessLog(1, 200, 0, REQUEST_TIME);
+ }
+
+ private static class DispatchingServletTracking extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ private final String target;
+ private final boolean addTrackingListener;
+
+ public DispatchingServletTracking(String target, boolean
addTrackingListener) {
+ this.target = target;
+ this.addTrackingListener = addTrackingListener;
+ }
+
+ @Override
+ protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ throws ServletException, IOException {
+ track("doGet-startAsync-");
+ AsyncContext ac = req.startAsync();
+ if (addTrackingListener) {
+ ac.addListener(new StickyTrackingListener(false, false, null));
+ }
+ ac.dispatch(target);
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]