Index: test/org/apache/catalina/core/TestAsyncContextImpl.java =================================================================== --- test/org/apache/catalina/core/TestAsyncContextImpl.java (revision 1739975) +++ test/org/apache/catalina/core/TestAsyncContextImpl.java (working copy) @@ -16,44 +16,11 @@ */ package org.apache.catalina.core; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import javax.servlet.AsyncContext; -import javax.servlet.AsyncEvent; -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; -import javax.servlet.ServletRequestListener; -import javax.servlet.ServletRequestWrapper; -import javax.servlet.ServletResponse; -import javax.servlet.ServletResponseWrapper; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import org.junit.Assert; -import org.junit.Test; - import org.apache.catalina.Context; import org.apache.catalina.Wrapper; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; +import org.apache.catalina.startup.TesterServlet; import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.TomcatBaseTest; import org.apache.catalina.valves.TesterAccessLogValve; @@ -61,7 +28,24 @@ import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.descriptor.web.ErrorPage; import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Test; +import javax.servlet.*; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import static org.junit.Assert.*; + public class TestAsyncContextImpl extends TomcatBaseTest { // Time for a request to process (need to allow for threads to start etc.) @@ -1822,6 +1806,99 @@ } @Test + public void testBug59219() throws Exception{ + resetTracker(); + Tomcat tomcat = getTomcatInstance(); + + Context ctx = tomcat.addContext("", null); +// tomcat.addServlet("", "async", new Bug59219Servlet()) + tomcat.addServlet("", "async", new Bug59219Servlet()) + .setAsyncSupported(true); + ctx.addServletMapping("/async", "async"); + + tomcat.start(); + + //Point 2. + ByteChunk body = getUrl("http://localhost:" + getPort() + "/async"); + String expected = "doGet-onError"; + + //Just let's give it 5 seconds :) + int count = 0; + while(!expected.equals(body.toString()) || count < 100) { + Thread.sleep(50); + count++; + } + + Assert.assertEquals(expected, body.toString()); + + //Point 3. + body = getUrl("http://localhost:" + getPort() + "/async?loops=3"); + expected = "doGet-doGet-doGet-onError"; + + count = 0; + while(!expected.equals(body.toString()) || count < 100) { + Thread.sleep(50); + count++; + } + + Assert.assertEquals(expected, body.toString()); + } + + private static class Bug59219Servlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + resp.setContentType("text/html"); + AsyncContext ctx = req.startAsync(); + ctx.addListener(new Bug59219Listener()); + resp.getWriter().write("doGet-"); + + String loop = req.getParameter("loop"); + Integer iloop = (Integer) req.getAttribute("iloop"); + + if (iloop == null) { + iloop = 0; + if (loop != null) + iloop = Integer.parseInt(loop); + } + + if (iloop > 0) { + iloop--; + req.setAttribute("iloop", iloop); + ctx.dispatch(); + } else + throw new ServletException("container be nice and process onError."); + } + + } + + private static class Bug59219Listener implements AsyncListener { + + @Override + public void onComplete(AsyncEvent ae) throws IOException { + // Nothing. + } + + @Override + public void onTimeout(AsyncEvent ae) throws IOException { + // Nothing. + } + + @Override + public void onError(AsyncEvent ae) throws IOException { + ae.getAsyncContext().getResponse().getWriter() + .write("onError"); + } + + @Override + public void onStartAsync(AsyncEvent ae) throws IOException { + // Nothing. + } + } + + @Test public void testForbiddenDispatching() throws Exception { resetTracker(); // Setup Tomcat instance