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


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

commit 42a1b2158be9f774e0c86f318f5b207c7b0d4c46
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 b2f9d09..c403315 100644
--- a/java/org/apache/coyote/InputBuffer.java
+++ b/java/org/apache/coyote/InputBuffer.java
@@ -61,4 +61,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 e65486d..43e7366 100644
--- a/java/org/apache/coyote/ajp/AjpProcessor.java
+++ b/java/org/apache/coyote/ajp/AjpProcessor.java
@@ -1189,7 +1189,7 @@ public class AjpProcessor extends AbstractProcessor {
         if (empty) {
             return 0;
         } else {
-            return bodyBytes.getByteChunk().getLength();
+            return request.getInputBuffer().available();
         }
     }
 
@@ -1455,6 +1455,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 fe9cc96..a3f9a46 100644
--- a/java/org/apache/coyote/http11/Http11InputBuffer.java
+++ b/java/org/apache/coyote/http11/Http11InputBuffer.java
@@ -257,12 +257,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);
-
+        }
     }
 
 
@@ -662,17 +661,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;
         }
@@ -1161,6 +1168,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 bd119d2..eceeacb 100644
--- a/java/org/apache/coyote/http11/filters/BufferedInputFilter.java
+++ b/java/org/apache/coyote/http11/filters/BufferedInputFilter.java
@@ -159,7 +159,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 c284b64..b22a0d3 100644
--- a/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
+++ b/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
@@ -303,7 +303,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 8594804..1b4d11e 100644
--- a/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
+++ b/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
@@ -214,7 +214,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 bf13b11..45fc82a 100644
--- a/java/org/apache/coyote/http2/Stream.java
+++ b/java/org/apache/coyote/http2/Stream.java
@@ -1229,7 +1229,8 @@ public class Stream extends AbstractStream implements HeaderEmitter {
         }
 
 
-        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 b40ba26..0bd9c23 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 8.5.58 (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]