Hi Mark, Unit test failed because of this commit. Full details can be found in [1].
Test case failure exception stack trace: Testcase: testZeroLengthRequestBodyPostA took 3.038 sec FAILED expected:<200> but was:<500> junit.framework.AssertionFailedError: expected:<200> but was:<500> at org.apache.coyote.ajp.TestAbstractAjpProcessor.validateResponseHeaders(TestAbstractAjpProcessor.java:830) at org.apache.coyote.ajp.TestAbstractAjpProcessor.doTestZeroLengthRequestBody(TestAbstractAjpProcessor.java:743) at org.apache.coyote.ajp.TestAbstractAjpProcessor.testZeroLengthRequestBodyPostA(TestAbstractAjpProcessor.java:706) 06-Nov-2015 10:44:32.685 SEVERE [ajp-apr-127.0.0.1-auto-7-exec-1] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [ReadBody] in context with path [] threw exception java.lang.UnsupportedOperationException: The Comet protocol is not supported by this connector at org.apache.coyote.ajp.AbstractAjpProcessor.action(AbstractAjpProcessor.java:622) at org.apache.coyote.Request.action(Request.java:380) at org.apache.catalina.connector.InputBuffer.available(InputBuffer.java:249) at org.apache.catalina.connector.CoyoteInputStream.available(CoyoteInputStream.java:124) at org.apache.coyote.ajp.TestAbstractAjpProcessor$ReadBodyServlet.doRequest(TestAbstractAjpProcessor.java:968) at org.apache.coyote.ajp.TestAbstractAjpProcessor$ReadBodyServlet.doPost(TestAbstractAjpProcessor.java:955) at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) at org.apache.coyote.ajp.AbstractAjpProcessor.process(AbstractAjpProcessor.java:849) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) at org.apache.tomcat.util.net.AprEndpoint$SocketWithOptionsProcessor.run(AprEndpoint.java:2437) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745) If protocol is AJP, AbstractAjpProcessor.action will throw UnsupportedOperationException. In org.apache.catalina.connector.InputBuffer#avaliable(), readForAvailable is not enough to avoid IS_COMET action. I think we should also check the protocol, since IS_COMET only support HTTP. The only way to I can figure out is to use Thread.currentThread.getName().isStartsWith("http"), but maybe there is something better. [1] http://vmgump.apache.org/gump/public/tomcat-8.0.x/tomcat-tc8.0.x-test-bio/index.html Thanks, Huxing Zhang ------------------------------------------------------------------ From:markt <ma...@apache.org> Time:2015 Nov 4 (Wed) 18:55 To:dev <dev@tomcat.apache.org> Subject:svn commit: r1712529 - in /tomcat/tc8.0.x/trunk/java/org/apache: catalina/connector/ catalina/core/ coyote/ coyote/ajp/ coyote/http11/ Author: markt Date: Wed Nov 4 10:55:12 2015 New Revision: 1712529 URL: http://svn.apache.org/viewvc?rev=1712529&view=rev Log: Follow-up to r1712081. Comet is not-blocking too, so it also needs to trigger a read on a call to available() if no bytes are in the buffer Modified: tomcat/tc8.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java tomcat/tc8.0.x/trunk/java/org/apache/catalina/connector/InputBuffer.java tomcat/tc8.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/ActionCode.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java Modified: tomcat/tc8.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=1712529&r1=1712528&r2=1712529&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Wed Nov 4 10:55:12 2015 @@ -519,15 +519,11 @@ public class CoyoteAdapter implements Ad if (request.isComet()) { if (!response.isClosed() && !response.isError()) { + comet = true; + res.action(ActionCode.COMET_BEGIN, null); if (request.getAvailable() || (request.getContentLength() > 0 && (!request.isParametersParsed()))) { // Invoke a read event right away if there are available bytes - if (event(req, res, SocketStatus.OPEN_READ)) { - comet = true; - res.action(ActionCode.COMET_BEGIN, null); - } - } else { - comet = true; - res.action(ActionCode.COMET_BEGIN, null); + event(req, res, SocketStatus.OPEN_READ); } } else { // Clear the filter chain, as otherwise it will not be reset elsewhere @@ -535,8 +531,8 @@ public class CoyoteAdapter implements Ad request.setFilterChain(null); } } - } + AsyncContextImpl asyncConImpl = (AsyncContextImpl)request.getAsyncContext(); if (asyncConImpl != null) { async = true; Modified: tomcat/tc8.0.x/trunk/java/org/apache/catalina/connector/InputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/catalina/connector/InputBuffer.java?rev=1712529&r1=1712528&r2=1712529&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/catalina/connector/InputBuffer.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/catalina/connector/InputBuffer.java Wed Nov 4 10:55:12 2015 @@ -22,6 +22,7 @@ import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; import javax.servlet.ReadListener; @@ -241,7 +242,14 @@ public class InputBuffer extends Reader available = cb.getLength(); } if (available == 0) { - coyoteRequest.action(ActionCode.AVAILABLE, Boolean.valueOf(coyoteRequest.getReadListener() != null)); + // Written this way to avoid use of IS_COMET action where possible + boolean readForAvailable = coyoteRequest.getReadListener() != null; + if (!readForAvailable) { + AtomicBoolean isComet = new AtomicBoolean(); + coyoteRequest.action(ActionCode.IS_COMET, isComet); + readForAvailable = isComet.get(); + } + coyoteRequest.action(ActionCode.AVAILABLE, Boolean.valueOf(readForAvailable)); available = (coyoteRequest.getAvailable() > 0) ? 1 : 0; } return available; Modified: tomcat/tc8.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java?rev=1712529&r1=1712528&r2=1712529&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/catalina/core/StandardWrapperValve.java Wed Nov 4 10:55:12 2015 @@ -181,9 +181,6 @@ final class StandardWrapperValve ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet); - // Reset comet flag value after creating the filter chain - request.setComet(false); - // Call the filter chain for this request // NOTE: This also calls the servlet's service() method try { @@ -196,7 +193,6 @@ final class StandardWrapperValve ((AsyncContextImpl)request.getAsyncContext()).doInternalDispatch(); } else if (comet) { filterChain.doFilterEvent(request.getEvent()); - request.setComet(true); } else { filterChain.doFilter(request.getRequest(), response.getResponse()); @@ -211,7 +207,6 @@ final class StandardWrapperValve if (request.isAsyncDispatching()) { ((AsyncContextImpl)request.getAsyncContext()).doInternalDispatch(); } else if (comet) { - request.setComet(true); filterChain.doFilterEvent(request.getEvent()); } else { filterChain.doFilter Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/ActionCode.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/ActionCode.java?rev=1712529&r1=1712528&r2=1712529&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/ActionCode.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/ActionCode.java Wed Nov 4 10:55:12 2015 @@ -135,6 +135,11 @@ public enum ActionCode { COMET_SETTIMEOUT, /** + * Callback to determine if the current request is a Comet request. + */ + IS_COMET, + + /** * Callback for an async request. */ ASYNC_START, Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java?rev=1712529&r1=1712528&r2=1712529&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/ajp/AbstractAjpProcessor.java Wed Nov 4 10:55:12 2015 @@ -617,6 +617,11 @@ public abstract class AbstractAjpProcess throw new UnsupportedOperationException( sm.getString("ajpprocessor.comet.notsupported")); } + case IS_COMET: { + // HTTP connections only. Unsupported for AJP. + throw new UnsupportedOperationException( + sm.getString("ajpprocessor.comet.notsupported")); + } case AVAILABLE: { if (available()) { request.setAvailable(1); Modified: tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java URL: http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java?rev=1712529&r1=1712528&r2=1712529&view=diff ============================================================================== --- tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java (original) +++ tomcat/tc8.0.x/trunk/java/org/apache/coyote/http11/AbstractHttp11Processor.java Wed Nov 4 10:55:12 2015 @@ -920,6 +920,11 @@ public abstract class AbstractHttp11Proc endRequest(); break; } + case IS_COMET: { + AtomicBoolean result = (AtomicBoolean) param; + result.set(isComet()); + break; + } default: { actionInternal(actionCode, param); break; --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org