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 <ma...@apache.org> 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: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org