You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2020/07/08 22:03:51 UTC
[tomcat] branch 9.0.x updated: Refactor sis.available() for more
accurate return value
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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org