Hello Mark,

> -----Ursprüngliche Nachricht-----
> Von: Mark Thomas <ma...@apache.org>
> Gesendet: Montag, 7. November 2022 12:43
> An: users@tomcat.apache.org
> Betreff: Re: Tomcat 10 with Http2 and compression sometimes causes pages to
> load partly in FF
> 
> 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

Thank you so much for investigating this.
As far as I saw in the Wireshark dump, the Firefox-Browser is closing one http2 
stream (don’t know why FF behaves like that).
It seems FF is fetching cached resources and after fetching recognizes that it 
doesn’t need it.
So the reason is that the browser is cancelling / closing the http2-stream.
The closed stream happens in version 10.0.0-M7 and 10.0.0-M8 but only causes 
issues in version M8. Thus I assume that the issue is somewhere later on in the 
handling.

Strangely it causes only problems in connection with the compression=on/force 
setting.

Reply via email to