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