You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/09/03 19:47:24 UTC

svn commit: r1519766 - in /tomcat/trunk: java/org/apache/catalina/connector/CoyoteInputStream.java java/org/apache/catalina/connector/InputBuffer.java test/org/apache/catalina/nonblocking/TestNonBlockingAPI.java

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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org