[tomcat] branch master 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 master 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 master
in repository https://gitbox.apache.org/repos/asf/tomcat.git


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

commit 15725e7569efd91debfaaf75e99e8f88e0be9a36
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                         |  5 ++++
 9 files changed, 64 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 77d6a94..19752dd 100644
--- a/java/org/apache/coyote/ajp/AjpProcessor.java
+++ b/java/org/apache/coyote/ajp/AjpProcessor.java
@@ -1087,7 +1087,7 @@ public class AjpProcessor extends AbstractProcessor {
         if (empty) {
             return 0;
         } else {
-            return bodyBytes.getByteChunk().getLength();
+            return request.getInputBuffer().available();
         }
     }
 
@@ -1309,6 +1309,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 8619a32..822558f0 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 b43629c7..396a24e 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 9c28f1a..11acb74 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -51,6 +51,11 @@
         Remove deprecated <code>CookieProcessor.generateHeader</code> method.
         (remm)
       </fix>
+      <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">


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