Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.12.1
-
None
-
6c0ced4b7a77b089b434ab5eb9f430717f26d687 (qt/qtbase/5.12)
Description
I've been debugging a networking problemĀ in https://github.com/owncloud/client/issues/7020#issuecomment-465578496 and I think the issue is in Qt's HTTP2 stack.
The symptom is QNetworkReply emitting finished() with NoError even though the request hasn't properly finished. A warning like 'stream 15 finished with error: ""' is seen.
Analysis (from mitmproxy talking to the server, so not entirely reliable, but shows what's going on):
- Client opens HTTP2 connection
- Requests data on streams 1, 3, 5, 7, 9
- Stream 1, 9 finish; Stream 3, 5, 7 are still streaming DATA frames and are not finished
- There's a GOAWAY 2^31-1 no-error frame from the server
- mitmproxy closes the connection with a tls close_notify
- there are more DATA frames from the server on streams 3, 7 that aren't ACKed by the client
- finally a GOAWAY 9 no-error frame, and the server's close_notify
If I read qhttp2protocolhandler.cpp correctly the problem is that the GOAWAY with a lastStreamID of 2^31-1 causes Qt to terminate all running streams. Specifically:
} else if (lastStreamID >= nextID) { // "A server that is attempting to gracefully shut down a connection SHOULD // send an initial GOAWAY frame with the last stream identifier set to 2^31-1 // and a NO_ERROR code." if (lastStreamID != Http2::lastValidStreamID || errorCode != HTTP2_NO_ERROR) return connectionError(PROTOCOL_ERROR, "GOAWAY invalid stream/error code"); lastStreamID = 1; // <- causes all streams to be closed } else {
The GOAWAY spec says that the streams should not be closed at this point.
Attachments
For Gerrit Dashboard: QTBUG-73947 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
254111,6 | HTTP2: Fix handling of GOAWAY frames | 5.12 | qt/qtbase | Status: MERGED | +2 | 0 |