Author: markt Date: Tue Sep 3 17:47:24 2013 New Revision: 1519766 URL: http://svn.apache.org/r1519766 Log: Add state checks to non-blocking reads that match those for non-blocking writes.
Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteInputStream.java tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java tomcat/trunk/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteInputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CoyoteInputStream.java?rev=1519766&r1=1519765&r2=1519766&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/CoyoteInputStream.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/CoyoteInputStream.java Tue Sep 3 17:47:24 2013 @@ -25,6 +25,7 @@ import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import org.apache.catalina.security.SecurityUtil; +import org.apache.tomcat.util.res.StringManager; /** * This class handles reading bytes. @@ -32,27 +33,20 @@ import org.apache.catalina.security.Secu * @author Remy Maucherat * @author Jean-Francois Arcand */ -public class CoyoteInputStream - extends ServletInputStream { +public class CoyoteInputStream extends ServletInputStream { - - // ----------------------------------------------------- Instance Variables + protected static final StringManager sm = + StringManager.getManager(Constants.Package); protected InputBuffer ib; - // ----------------------------------------------------------- Constructors - - protected CoyoteInputStream(InputBuffer ib) { this.ib = ib; } - // -------------------------------------------------------- Package Methods - - /** * Clear facade. */ @@ -61,25 +55,19 @@ public class CoyoteInputStream } - // --------------------------------------------------------- Public Methods - - /** * Prevent cloning the facade. */ @Override - protected Object clone() - throws CloneNotSupportedException { + protected Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } - // --------------------------------------------- ServletInputStream Methods - - @Override - public int read() - throws IOException { + public int read() throws IOException { + checkNonBlockingRead(); + if (SecurityUtil.isPackageProtectionEnabled()){ try{ @@ -140,6 +128,7 @@ public class CoyoteInputStream @Override public int read(final byte[] b) throws IOException { + checkNonBlockingRead(); if (SecurityUtil.isPackageProtectionEnabled()){ try{ @@ -173,6 +162,7 @@ public class CoyoteInputStream @Override public int read(final byte[] b, final int off, final int len) throws IOException { + checkNonBlockingRead(); if (SecurityUtil.isPackageProtectionEnabled()){ try{ @@ -258,4 +248,12 @@ public class CoyoteInputStream public void setReadListener(ReadListener listener) { ib.setReadListener(listener); } + + + private void checkNonBlockingRead() { + if (ib.isBlocking() && !ib.isReady()) { + throw new IllegalStateException( + sm.getString("coyoteInputStream.nbNotready")); + } + } } Modified: tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java?rev=1519766&r1=1519765&r2=1519766&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/InputBuffer.java Tue Sep 3 17:47:24 2013 @@ -282,6 +282,11 @@ public class InputBuffer extends Reader } + boolean isBlocking() { + return coyoteRequest.getReadListener() != null; + } + + // ------------------------------------------------- Bytes Handling Methods /** Modified: tomcat/trunk/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java?rev=1519766&r1=1519765&r2=1519766&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java (original) +++ tomcat/trunk/test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java Tue Sep 3 17:47:24 2013 @@ -80,15 +80,27 @@ public class TestNonBlockingAPI extends } } + @Test public void testNonBlockingRead() throws Exception { + doTestNonBlockingRead(false); + } + + + @Test(expected=IOException.class) + public void testNonBlockingReadIgnoreIsReady() throws Exception { + doTestNonBlockingRead(true); + } + + + private void doTestNonBlockingRead(boolean ignoreIsReady) throws Exception { Tomcat tomcat = getTomcatInstance(); // Must have a real docBase - just use temp StandardContext ctx = (StandardContext) tomcat.addContext("", System.getProperty("java.io.tmpdir")); - NBReadServlet servlet = new NBReadServlet(); + NBReadServlet servlet = new NBReadServlet(ignoreIsReady); String servletName = NBReadServlet.class.getName(); Tomcat.addServlet(ctx, servletName, servlet); ctx.addServletMapping("/", servletName); @@ -98,6 +110,7 @@ public class TestNonBlockingAPI extends Map<String, List<String>> resHeaders = new HashMap<>(); int rc = postUrl(true, new DataWriter(500), "http://localhost:" + getPort() + "/", new ByteChunk(), resHeaders, null); + Assert.assertEquals(HttpServletResponse.SC_OK, rc); } @@ -420,7 +433,13 @@ public class TestNonBlockingAPI extends @WebServlet(asyncSupported = true) public class NBReadServlet extends TesterServlet { private static final long serialVersionUID = 1L; + private final boolean ignoreIsReady; public volatile TestReadListener listener; + + public NBReadServlet(boolean ignoreIsReady) { + this.ignoreIsReady = ignoreIsReady; + } + @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // step 1 - start async @@ -454,7 +473,7 @@ public class TestNonBlockingAPI extends }); // step 2 - notify on read ServletInputStream in = req.getInputStream(); - listener = new TestReadListener(actx, false); + listener = new TestReadListener(actx, false, ignoreIsReady); in.setReadListener(listener); } } @@ -498,7 +517,7 @@ public class TestNonBlockingAPI extends }); // step 2 - notify on read ServletInputStream in = req.getInputStream(); - rlistener = new TestReadListener(actx, true); + rlistener = new TestReadListener(actx, true, false); in.setReadListener(rlistener); ServletOutputStream out = resp.getOutputStream(); resp.setBufferSize(200 * 1024); @@ -529,15 +548,18 @@ public class TestNonBlockingAPI extends private class TestReadListener implements ReadListener { private final AsyncContext ctx; - private final StringBuilder body = new StringBuilder(); private final boolean usingNonBlockingWrite; + private final boolean ignoreIsReady; + private final StringBuilder body = new StringBuilder(); public volatile boolean onErrorInvoked = false; public TestReadListener(AsyncContext ctx, - boolean usingNonBlockingWrite) { + boolean usingNonBlockingWrite, + boolean ignoreIsReady) { this.ctx = ctx; this.usingNonBlockingWrite = usingNonBlockingWrite; + this.ignoreIsReady = ignoreIsReady; } @Override @@ -552,7 +574,7 @@ public class TestNonBlockingAPI extends break; } s += new String(b, 0, read); - } while (in.isReady()); + } while (ignoreIsReady || in.isReady()); log.info(s); body.append(s); } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org