Class GzipSupport.OptimisticAvailabilityInputStream
- All Implemented Interfaces:
Closeable
,AutoCloseable
- Enclosing class:
GzipSupport
GZIPInputStream
completes processing an individual member it will call InputStream.available()
to determine if there is more stream to try and process. If the call
to available()
returns 0 GZIPInputStream
will determine it has processed the
entirety of the underlying stream. This is spurious, as InputStream.available()
is
allowed to return 0 if it would require blocking in order for more bytes to be available. When
GZIPInputStream
is reading from a Transfer-Encoding: chunked
response, if the
chunk boundary happens to align closely enough to the member boundary GZIPInputStream
won't consume the whole response.
This class, provides an optimistic "estimate" (in actuality, a lie) of the number of
available()
bytes in the underlying stream. It does this by tracking the last number of bytes
read. If the last number of bytes read is grater than -1, we return Integer.MAX_VALUE
to any call of available()
.
We're breaking the contract of available() in that we're lying about how much data we have
accessible without blocking, however in the case where we're weaving GZIPInputStream
into response processing we already know there are going to be blocking calls to read before
the stream is exhausted.
This scenario isn't unique to processing of chunked responses, and can be replicated
reliably using a SequenceInputStream
with two underlying ByteArrayInputStream
. See the corresponding test class for a reproduction.
The need for this class has been verified for the following JVMs:
-
openjdk version "1.8.0_292" OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_292-b10) OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.292-b10, mixed mode)
-
openjdk version "11.0.14.1" 2022-02-08 OpenJDK Runtime Environment Temurin-11.0.14.1+1 (build 11.0.14.1+1) OpenJDK 64-Bit Server VM Temurin-11.0.14.1+1 (build 11.0.14.1+1, mixed mode)
-
openjdk version "17" 2021-09-14 OpenJDK Runtime Environment Temurin-17+35 (build 17+35) OpenJDK 64-Bit Server VM Temurin-17+35 (build 17+35, mixed mode, sharing)
-
Field Summary
FieldsFields inherited from class java.io.FilterInputStream
in
-
Constructor Summary
Constructors -
Method Summary
Methods inherited from class java.io.FilterInputStream
close, mark, markSupported, reset, skip
-
Field Details
-
lastRead
private int lastRead
-
-
Constructor Details
-
OptimisticAvailabilityInputStream
OptimisticAvailabilityInputStream(InputStream delegate)
-
-
Method Details
-
available
- Overrides:
available
in classFilterInputStream
- Throws:
IOException
-
read
- Overrides:
read
in classFilterInputStream
- Throws:
IOException
-
read
- Overrides:
read
in classFilterInputStream
- Throws:
IOException
-
read
- Overrides:
read
in classFilterInputStream
- Throws:
IOException
-