diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2019-09-04 15:00:31 +0200 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2019-09-05 20:40:30 +0200 |
commit | 543769666f18f79bd6ebd6119a39834aafc2b0df (patch) | |
tree | 362f3969bee0b2795614a9d49e62b9b2b3ae65be /src/network/access/qhttp2protocolhandler.cpp | |
parent | d49daa3f2737be5c5cbdae3e6b1b2651489a0686 (diff) |
A follow-up to a recent fix in QHttpNetworkConnectionChannel
While working with HTTP/2, we are not re-sending failed requests.
In case we receive a GOAWAY frame, we properly handle it by
processing some active streams if possible, and aborting streams
that will not proceed further with ContentResendError. But it's
possible that some server failed to send us GOAWAY (for example,
it died) or closed the connection not finishing the streams that
were still active and valid (ID <= value from GOAWAY frame).
Now that we will not re-connect, there is no reason to be quiet
about us not progressing - emit RemoteHostClosedError on any
remaining active stream/request we cannot process further.
Fixes: QTBUG-77852
Change-Id: I4cd68a1c8c103b1fbe36c20a1cc406ab2e20dd12
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/network/access/qhttp2protocolhandler.cpp')
-rw-r--r-- | src/network/access/qhttp2protocolhandler.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index c1053882af..9bf5547f15 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -58,6 +58,8 @@ #include <QtNetwork/qnetworkproxy.h> #endif +#include <qcoreapplication.h> + #include <algorithm> #include <vector> @@ -195,6 +197,29 @@ QHttp2ProtocolHandler::QHttp2ProtocolHandler(QHttpNetworkConnectionChannel *chan } } +void QHttp2ProtocolHandler::handleConnectionClosure() +{ + // The channel has just received RemoteHostClosedError and since it will + // not try (for HTTP/2) to re-connect, it's time to finish all replies + // with error. + + // Maybe we still have some data to read and can successfully finish + // a stream/request? + _q_receiveReply(); + + // Finish all still active streams. If we previously had GOAWAY frame, + // we probably already closed some (or all) streams with ContentReSend + // error, but for those still active, not having any data to finish, + // we now report RemoteHostClosedError. + const auto errorString = QCoreApplication::translate("QHttp", "Connection closed"); + for (auto it = activeStreams.begin(), eIt = activeStreams.end(); it != eIt; ++it) + finishStreamWithError(it.value(), QNetworkReply::RemoteHostClosedError, errorString); + + // Make sure we'll never try to read anything later: + activeStreams.clear(); + goingAway = true; +} + void QHttp2ProtocolHandler::_q_uploadDataReadyRead() { if (!sender()) // QueuedConnection, firing after sender (byte device) was deleted. |