- Add more accurate available() method, using a new action (still very cheap to invok...
authorremm <remm@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 27 Apr 2007 17:04:36 +0000 (17:04 +0000)
committerremm <remm@13f79535-47bb-0310-9956-ffa450edef68>
Fri, 27 Apr 2007 17:04:36 +0000 (17:04 +0000)
- This is mostly useful for Comet, since it can be difficult to know for sure if reading is possible without
  blocking if the beginning of the entity body was sent along with the request header in a single packet.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@533164 13f79535-47bb-0310-9956-ffa450edef68

14 files changed:
java/org/apache/catalina/connector/CoyoteInputStream.java
java/org/apache/catalina/connector/InputBuffer.java
java/org/apache/coyote/ActionCode.java
java/org/apache/coyote/Request.java
java/org/apache/coyote/http11/Http11AprProcessor.java
java/org/apache/coyote/http11/Http11NioProcessor.java
java/org/apache/coyote/http11/InputFilter.java
java/org/apache/coyote/http11/InternalAprInputBuffer.java
java/org/apache/coyote/http11/InternalNioInputBuffer.java
java/org/apache/coyote/http11/filters/BufferedInputFilter.java
java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
java/org/apache/coyote/http11/filters/IdentityInputFilter.java
java/org/apache/coyote/http11/filters/SavedRequestInputFilter.java
java/org/apache/coyote/http11/filters/VoidInputFilter.java

index c41c866..e7358a9 100644 (file)
@@ -228,7 +228,7 @@ public class CoyoteInputStream
             }
         } else {
              ib.close();
-        }            
+        }
     }
 
 }
index c380d33..08829e5 100644 (file)
@@ -25,6 +25,7 @@ import java.security.PrivilegedExceptionAction;
 import java.util.HashMap;
 
 import org.apache.catalina.security.SecurityUtil;
+import org.apache.coyote.ActionCode;
 import org.apache.coyote.Request;
 import org.apache.tomcat.util.buf.B2CConverter;
 import org.apache.tomcat.util.buf.ByteChunk;
@@ -258,13 +259,17 @@ public class InputBuffer extends Reader
 
     public int available()
         throws IOException {
+        int available = 0;
         if (state == BYTE_STATE) {
-            return bb.getLength();
+            available = bb.getLength();
         } else if (state == CHAR_STATE) {
-            return cb.getLength();
-        } else {
-            return 0;
+            available = cb.getLength();
+        }
+        if (available == 0) {
+            coyoteRequest.action(ActionCode.ACTION_AVAILABLE, null);
+            available = (coyoteRequest.getAvailable() > 0) ? 1 : 0;
         }
+        return available;
     }
 
 
@@ -411,7 +416,7 @@ public class InputBuffer extends Reader
 
     public boolean ready()
         throws IOException {
-        return (cb.getLength() > 0);
+        return (available() > 0);
     }
 
 
index 41a000d..1bc8622 100644 (file)
@@ -146,6 +146,12 @@ public final class ActionCode {
     public static final ActionCode ACTION_COMET_END = new ActionCode(22);
 
 
+    /**
+     * Callback for getting the amount of available bytes
+     */
+    public static final ActionCode ACTION_AVAILABLE = new ActionCode(23);
+
+
     // ----------------------------------------------------------- Constructors
     int code;
 
index 63c1e3d..6c88973 100644 (file)
@@ -143,6 +143,7 @@ public final class Request {
     private int bytesRead=0;
     // Time of the request - usefull to avoid repeated calls to System.currentTime
     private long startTime = 0L;
+    private int available = 0;
 
     private RequestInfo reqProcessorMX=new RequestInfo(this);
     // ------------------------------------------------------------- Properties
@@ -392,6 +393,14 @@ public final class Request {
         return authType;
     }
 
+    public int getAvailable() {
+        return available;
+    }
+
+    public void setAvailable(int available) {
+        this.available = available;
+    }
+
     // -------------------- Input Buffer --------------------
 
 
@@ -484,6 +493,7 @@ public final class Request {
         serverPort=-1;
         localPort = -1;
         remotePort = -1;
+        available = 0;
 
         cookies.recycle();
         parameters.recycle();
index 265068e..3d7eaad 100644 (file)
@@ -1192,6 +1192,8 @@ public class Http11AprProcessor implements ActionHook {
                 request.getInputBuffer();
             internalBuffer.addActiveFilter(savedBody);
             
+        } else if (actionCode == ActionCode.ACTION_AVAILABLE) {
+            request.setAvailable(inputBuffer.available());
         } else if (actionCode == ActionCode.ACTION_COMET_BEGIN) {
             comet = true;
         } else if (actionCode == ActionCode.ACTION_COMET_END) {
index 6fd23fd..b74d550 100644 (file)
@@ -1221,6 +1221,8 @@ public class Http11NioProcessor implements ActionHook {
                 request.getInputBuffer();
             internalBuffer.addActiveFilter(savedBody);
 
+        } else if (actionCode == ActionCode.ACTION_AVAILABLE) {
+            request.setAvailable(inputBuffer.available());
         } else if (actionCode == ActionCode.ACTION_COMET_BEGIN) {
             comet = true;
         } else if (actionCode == ActionCode.ACTION_COMET_END) {
index 661290f..27aa013 100644 (file)
@@ -79,4 +79,10 @@ public interface InputFilter extends InputBuffer {
         throws IOException;
 
 
+    /**
+     * Amount of bytes still available in a buffer.
+     */
+    public int available();
+
+
 }
index 7366eea..4286458 100644 (file)
@@ -673,6 +673,20 @@ public class InternalAprInputBuffer implements InputBuffer {
 
     }
 
+    
+    /**
+     * Available bytes (note that due to encoding, this may not correspond )
+     */
+    public int available() {
+        int result = (lastValid - pos);
+        if ((result == 0) && (lastActiveFilter >= 0)) {
+            for (int i = 0; (result == 0) && (i <= lastActiveFilter); i++) {
+                result = activeFilters[i].available();
+            }
+        }
+        return result;
+    }
+
 
     // ---------------------------------------------------- InputBuffer Methods
 
index ddbb028..30d598f 100644 (file)
@@ -798,6 +798,20 @@ public class InternalNioInputBuffer implements InputBuffer {
     }
 
 
+    /**
+     * Available bytes (note that due to encoding, this may not correspond )
+     */
+    public int available() {
+        int result = (lastValid - pos);
+        if ((result == 0) && (lastActiveFilter >= 0)) {
+            for (int i = 0; (result == 0) && (i <= lastActiveFilter); i++) {
+                result = activeFilters[i].available();
+            }
+        }
+        return result;
+    }
+
+
     // ---------------------------------------------------- InputBuffer Methods
 
 
index 768eebb..8795531 100644 (file)
@@ -120,4 +120,8 @@ public class BufferedInputFilter implements InputFilter {
         return 0;
     }
 
+    public int available() {
+        return buffered.getLength();
+    }
+    
 }
index 01eba2b..78ede73 100644 (file)
@@ -189,6 +189,14 @@ public class ChunkedInputFilter implements InputFilter {
 
 
     /**
+     * Amount of bytes still available in a buffer.
+     */
+    public int available() {
+        return (lastValid - pos);
+    }
+    
+
+    /**
      * Set the next buffer in the filter pipeline.
      */
     public void setBuffer(InputBuffer buffer) {
index 332ac15..5b13e85 100644 (file)
@@ -173,6 +173,14 @@ public class IdentityInputFilter implements InputFilter {
 
 
     /**
+     * Amount of bytes still available in a buffer.
+     */
+    public int available() {
+        return 0;
+    }
+    
+
+    /**
      * Set the next buffer in the filter pipeline.
      */
     public void setBuffer(InputBuffer buffer) {
index b49fbe5..60aef9a 100644 (file)
@@ -94,6 +94,13 @@ public class SavedRequestInputFilter implements InputFilter {
     }
 
     /**
+     * Amount of bytes still available in a buffer.
+     */
+    public int available() {
+        return input.getLength();
+    }
+    
+    /**
      * End the current request (has no effect).
      */
     public long end() throws IOException {
index 1b527e4..e08c59f 100644 (file)
@@ -116,4 +116,11 @@ public class VoidInputFilter implements InputFilter {
     }
 
 
+    /**
+     * Amount of bytes still available in a buffer.
+     */
+    public int available() {
+        return 0;
+    }
+    
 }