[tomcat] branch 9.0.x updated: Refactor sis.available() for more accurate return value

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[tomcat] branch 9.0.x updated: Refactor sis.available() for more accurate return value

markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/9.0.x by this push:
     new 1dc6503  Refactor sis.available() for more accurate return value
1dc6503 is described below

commit 1dc65035904b835b5e7a37eb43da4a76c2035509
Author: Mark Thomas <[hidden email]>
AuthorDate: Mon Jul 6 19:33:00 2020 +0100

    Refactor sis.available() for more accurate return value
---
 java/org/apache/coyote/InputBuffer.java            | 11 ++++++++
 java/org/apache/coyote/ajp/AjpProcessor.java       |  7 ++++-
 .../apache/coyote/http11/Http11InputBuffer.java    | 30 +++++++++++++++-------
 java/org/apache/coyote/http11/InputFilter.java     |  8 ------
 .../coyote/http11/filters/BufferedInputFilter.java |  8 +++++-
 .../coyote/http11/filters/ChunkedInputFilter.java  | 11 +++++++-
 .../coyote/http11/filters/IdentityInputFilter.java |  3 ++-
 java/org/apache/coyote/http2/Stream.java           |  3 ++-
 webapps/docs/changelog.xml                         |  9 +++++++
 9 files changed, 68 insertions(+), 22 deletions(-)

diff --git a/java/org/apache/coyote/InputBuffer.java b/java/org/apache/coyote/InputBuffer.java
index e30a51e..e836ee4 100644
--- a/java/org/apache/coyote/InputBuffer.java
+++ b/java/org/apache/coyote/InputBuffer.java
@@ -41,4 +41,15 @@ public interface InputBuffer {
      * @throws IOException If an I/O error occurs reading from the input stream
      */
     public int doRead(ApplicationBufferHandler handler) throws IOException;
+
+
+    /**
+     * Obtain an estimate of the number of bytes that can be read without
+     * blocking. Typically, this will be the number of available bytes known to
+     * be buffered.
+     *
+     * @return The number of bytes that can be read without blocking
+     */
+    public int available();
+
 }
diff --git a/java/org/apache/coyote/ajp/AjpProcessor.java b/java/org/apache/coyote/ajp/AjpProcessor.java
index 88f1cb7..730cbd1 100644
--- a/java/org/apache/coyote/ajp/AjpProcessor.java
+++ b/java/org/apache/coyote/ajp/AjpProcessor.java
@@ -1079,7 +1079,7 @@ public class AjpProcessor extends AbstractProcessor {
         if (empty) {
             return 0;
         } else {
-            return bodyBytes.getByteChunk().getLength();
+            return request.getInputBuffer().available();
         }
     }
 
@@ -1301,6 +1301,11 @@ public class AjpProcessor extends AbstractProcessor {
             empty = true;
             return handler.getByteBuffer().remaining();
         }
+
+        @Override
+        public int available() {
+            return bodyBytes.getByteChunk().getLength();
+        }
     }
 
 
diff --git a/java/org/apache/coyote/http11/Http11InputBuffer.java b/java/org/apache/coyote/http11/Http11InputBuffer.java
index 181d631..71ba804 100644
--- a/java/org/apache/coyote/http11/Http11InputBuffer.java
+++ b/java/org/apache/coyote/http11/Http11InputBuffer.java
@@ -242,12 +242,11 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler
 
     @Override
     public int doRead(ApplicationBufferHandler handler) throws IOException {
-
-        if (lastActiveFilter == -1)
+        if (lastActiveFilter == -1) {
             return inputStreamInputBuffer.doRead(handler);
-        else
+        } else {
             return activeFilters[lastActiveFilter].doRead(handler);
-
+        }
     }
 
 
@@ -648,17 +647,25 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler
     }
 
 
+    @Override
+    public int available() {
+        return available(false);
+    }
+
+
     /**
      * Available bytes in the buffers (note that due to encoding, this may not
      * correspond).
      */
     int available(boolean read) {
-        int available = byteBuffer.remaining();
-        if ((available == 0) && (lastActiveFilter >= 0)) {
-            for (int i = 0; (available == 0) && (i <= lastActiveFilter); i++) {
-                available = activeFilters[i].available();
-            }
+        int available;
+
+        if (lastActiveFilter == -1) {
+            available = inputStreamInputBuffer.available();
+        } else {
+            available = activeFilters[lastActiveFilter].available();
         }
+
         if (available > 0 || !read) {
             return available;
         }
@@ -1140,6 +1147,11 @@ public class Http11InputBuffer implements InputBuffer, ApplicationBufferHandler
 
             return length;
         }
+
+        @Override
+        public int available() {
+            return byteBuffer.remaining();
+        }
     }
 
 
diff --git a/java/org/apache/coyote/http11/InputFilter.java b/java/org/apache/coyote/http11/InputFilter.java
index 0d15490..a36c528 100644
--- a/java/org/apache/coyote/http11/InputFilter.java
+++ b/java/org/apache/coyote/http11/InputFilter.java
@@ -76,14 +76,6 @@ public interface InputFilter extends InputBuffer {
 
 
     /**
-     * Amount of bytes still available in a buffer.
-     *
-     * @return The number of bytes in the buffer
-     */
-    public int available();
-
-
-    /**
      * Has the request body been read fully?
      *
      * @return {@code true} if the request body has been fully read, otherwise
diff --git a/java/org/apache/coyote/http11/filters/BufferedInputFilter.java b/java/org/apache/coyote/http11/filters/BufferedInputFilter.java
index 1784cf3..fbc2b32 100644
--- a/java/org/apache/coyote/http11/filters/BufferedInputFilter.java
+++ b/java/org/apache/coyote/http11/filters/BufferedInputFilter.java
@@ -140,7 +140,13 @@ public class BufferedInputFilter implements InputFilter, ApplicationBufferHandle
 
     @Override
     public int available() {
-        return buffered.remaining();
+        int available = buffered.remaining();
+        if (available == 0) {
+            // No data buffered here. Try the next filter in the chain.
+            return buffer.available();
+        } else {
+            return available;
+        }
     }
 
 
diff --git a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
index c806ead..b59eb6e 100644
--- a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
+++ b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
@@ -243,7 +243,16 @@ public class ChunkedInputFilter implements InputFilter, ApplicationBufferHandler
      */
     @Override
     public int available() {
-        return readChunk != null ? readChunk.remaining() : 0;
+        int available = 0;
+        if (readChunk != null) {
+            available = readChunk.remaining();
+        }
+        if (available == 0) {
+            // No data buffered here. Try the next filter in the chain.
+            return buffer.available();
+        } else {
+            return available;
+        }
     }
 
 
diff --git a/java/org/apache/coyote/http11/filters/IdentityInputFilter.java b/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
index d9ffdf6..82c7ee3 100644
--- a/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
+++ b/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
@@ -176,7 +176,8 @@ public class IdentityInputFilter implements InputFilter, ApplicationBufferHandle
      */
     @Override
     public int available() {
-        return 0;
+        // No data buffered here. Try the next filter in the chain.
+        return buffer.available();
     }
 
 
diff --git a/java/org/apache/coyote/http2/Stream.java b/java/org/apache/coyote/http2/Stream.java
index 1ddf994..fa9394c 100644
--- a/java/org/apache/coyote/http2/Stream.java
+++ b/java/org/apache/coyote/http2/Stream.java
@@ -1171,7 +1171,8 @@ class Stream extends AbstractStream implements HeaderEmitter {
         }
 
 
-        final synchronized int available() {
+        @Override
+        public final synchronized int available() {
             if (inBuffer == null) {
                 return 0;
             }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index a2ff2ed..7ee0ca7 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -45,6 +45,15 @@
   issues do not "pop up" wrt. others).
 -->
 <section name="Tomcat 9.0.38 (markt)" rtext="in development">
+  <subsection name="Coyote">
+    <changelog>
+      <fix>
+        Refactor the implementation of
+        <code>ServletInputStream.available()</code> to provide a more accurate
+        return value, particularly when end of stream has been reached. (markt)
+      </fix>
+    </changelog>
+  </subsection>
   <subsection name="WebSocket">
     <changelog>
       <fix>


---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]