From: remm Date: Fri, 27 Apr 2007 17:04:36 +0000 (+0000) Subject: - Add more accurate available() method, using a new action (still very cheap to invok... X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=4cd6b75bb9c30e120527ef395339cb9312d0f99e;p=tomcat7.0 - Add more accurate available() method, using a new action (still very cheap to invoke, and quite simple). - 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 --- diff --git a/java/org/apache/catalina/connector/CoyoteInputStream.java b/java/org/apache/catalina/connector/CoyoteInputStream.java index c41c86680..e7358a975 100644 --- a/java/org/apache/catalina/connector/CoyoteInputStream.java +++ b/java/org/apache/catalina/connector/CoyoteInputStream.java @@ -228,7 +228,7 @@ public class CoyoteInputStream } } else { ib.close(); - } + } } } diff --git a/java/org/apache/catalina/connector/InputBuffer.java b/java/org/apache/catalina/connector/InputBuffer.java index c380d33ce..08829e5c4 100644 --- a/java/org/apache/catalina/connector/InputBuffer.java +++ b/java/org/apache/catalina/connector/InputBuffer.java @@ -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); } diff --git a/java/org/apache/coyote/ActionCode.java b/java/org/apache/coyote/ActionCode.java index 41a000d95..1bc862280 100644 --- a/java/org/apache/coyote/ActionCode.java +++ b/java/org/apache/coyote/ActionCode.java @@ -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; diff --git a/java/org/apache/coyote/Request.java b/java/org/apache/coyote/Request.java index 63c1e3d75..6c8897373 100644 --- a/java/org/apache/coyote/Request.java +++ b/java/org/apache/coyote/Request.java @@ -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(); diff --git a/java/org/apache/coyote/http11/Http11AprProcessor.java b/java/org/apache/coyote/http11/Http11AprProcessor.java index 265068ea4..3d7eaad46 100644 --- a/java/org/apache/coyote/http11/Http11AprProcessor.java +++ b/java/org/apache/coyote/http11/Http11AprProcessor.java @@ -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) { diff --git a/java/org/apache/coyote/http11/Http11NioProcessor.java b/java/org/apache/coyote/http11/Http11NioProcessor.java index 6fd23fd60..b74d5507d 100644 --- a/java/org/apache/coyote/http11/Http11NioProcessor.java +++ b/java/org/apache/coyote/http11/Http11NioProcessor.java @@ -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) { diff --git a/java/org/apache/coyote/http11/InputFilter.java b/java/org/apache/coyote/http11/InputFilter.java index 661290fd8..27aa013ab 100644 --- a/java/org/apache/coyote/http11/InputFilter.java +++ b/java/org/apache/coyote/http11/InputFilter.java @@ -79,4 +79,10 @@ public interface InputFilter extends InputBuffer { throws IOException; + /** + * Amount of bytes still available in a buffer. + */ + public int available(); + + } diff --git a/java/org/apache/coyote/http11/InternalAprInputBuffer.java b/java/org/apache/coyote/http11/InternalAprInputBuffer.java index 7366eea3b..428645813 100644 --- a/java/org/apache/coyote/http11/InternalAprInputBuffer.java +++ b/java/org/apache/coyote/http11/InternalAprInputBuffer.java @@ -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 diff --git a/java/org/apache/coyote/http11/InternalNioInputBuffer.java b/java/org/apache/coyote/http11/InternalNioInputBuffer.java index ddbb028a7..30d598ffd 100644 --- a/java/org/apache/coyote/http11/InternalNioInputBuffer.java +++ b/java/org/apache/coyote/http11/InternalNioInputBuffer.java @@ -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 diff --git a/java/org/apache/coyote/http11/filters/BufferedInputFilter.java b/java/org/apache/coyote/http11/filters/BufferedInputFilter.java index 768eebbb5..879553147 100644 --- a/java/org/apache/coyote/http11/filters/BufferedInputFilter.java +++ b/java/org/apache/coyote/http11/filters/BufferedInputFilter.java @@ -120,4 +120,8 @@ public class BufferedInputFilter implements InputFilter { return 0; } + public int available() { + return buffered.getLength(); + } + } diff --git a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java index 01eba2b07..78ede731f 100644 --- a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java +++ b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java @@ -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) { diff --git a/java/org/apache/coyote/http11/filters/IdentityInputFilter.java b/java/org/apache/coyote/http11/filters/IdentityInputFilter.java index 332ac150d..5b13e85e3 100644 --- a/java/org/apache/coyote/http11/filters/IdentityInputFilter.java +++ b/java/org/apache/coyote/http11/filters/IdentityInputFilter.java @@ -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) { diff --git a/java/org/apache/coyote/http11/filters/SavedRequestInputFilter.java b/java/org/apache/coyote/http11/filters/SavedRequestInputFilter.java index b49fbe5f9..60aef9a6e 100644 --- a/java/org/apache/coyote/http11/filters/SavedRequestInputFilter.java +++ b/java/org/apache/coyote/http11/filters/SavedRequestInputFilter.java @@ -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 { diff --git a/java/org/apache/coyote/http11/filters/VoidInputFilter.java b/java/org/apache/coyote/http11/filters/VoidInputFilter.java index 1b527e453..e08c59f20 100644 --- a/java/org/apache/coyote/http11/filters/VoidInputFilter.java +++ b/java/org/apache/coyote/http11/filters/VoidInputFilter.java @@ -116,4 +116,11 @@ public class VoidInputFilter implements InputFilter { } + /** + * Amount of bytes still available in a buffer. + */ + public int available() { + return 0; + } + }