On 06/11/2022 19:35, Thomas Hoffmann (Speed4Trade GmbH) wrote:
Hello Mark,
I found some time for digging into this older topic with the combination http2,
Firefox, Compression and only partly loaded pages.
I hope I or the topic doesn’t bother you.
Not at all. If there is a Tomcat bug here, I want to get it fixed.
As apache-tomcat-10.0.0-M7 doesn’t show the problem with broken pages in FF
(jsp page only partly loads) and
it showed up with apache-tomcat-10.0.0-M8, I was taking a look at the changes.
This was my current approach to this topic.
The change which makes the difference is in Http2UpgradeHandler:
int reserveWindowSize(Stream stream, int reservation, boolean block) throws
IOException {
...
if (!stream.canWrite()) {
stream.doStreamCancel(sm.getString("upgradeHandler.stream.notWritable",
stream.getConnectionId(), stream.getIdAsString()),
Http2Error.STREAM_CLOSED);
}
The older version just threw an exception instead of calling doStreamCancel
when the client is closing the stream:
if (!stream.canWrite()) {
throw new CloseNowException(
sm.getString("upgradeHandler.stream.notWritable",
stream.getConnectionId(),
stream.getIdentifier()));
}
The method doStreamCancel is setting some properties before throwing also a
CloseNowException:
void doStreamCancel(String msg, Http2Error error) throws CloseNowException
{
StreamException se = new StreamException(msg, error, getIdAsInt());
// Prevent the application making further writes
streamOutputBuffer.closed = true;
// Prevent Tomcat's error handling trying to write
coyoteResponse.setError();
coyoteResponse.setErrorReported();
// Trigger a reset once control returns to Tomcat
streamOutputBuffer.reset = se;
throw new CloseNowException(msg, se);
}
The line "streamOutputBuffer.closed = true;" seems to be responsible for the
partly shown pages in FF.
If I comment out this line, no problem shows up with FF, http2 and
compression="force".
Nice bit of detective work. Setting streamOutputBuffer.closed=true will
prevent the application from writing the rest of the resource content
which would explain the partial response seen on the client side.
This line seems to have some side effect somewhere else.
Unfortunately, I don’t know the code of Tomcat and http2 protocol.
Can you think about which side effect this line might have (in combination with
compression / GZipOutputFilter)?
Maybe you have an inspiring idea about the cause or have a hint, where to
follow the track.
I think this is more symptom rather than root cause. The symptom is
visible because of the change to call doStreamCancel() but the question
for me is what is triggering this to be called in the first place.
Digging into that a little:
stream.canWrite() needs to return false.
That happens when the Stream is in one of the states that does not
permit write. Those states are:
IDLE
RESERVED_LOCAL
HALF_CLOSED_LOCAL
CLOSED_RX
CLOSED_TX
CLOSED_RST_RX
CLOSED_RST_TX
One thing we could do is improve the error message so it logs the
current Stream state. That will help narrow down how the Stream got into
that state.
I'll get than done for the next set of releases.
Mark
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org