diff options
author | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2016-12-13 16:26:06 +0100 |
---|---|---|
committer | Timur Pocheptsov <timur.pocheptsov@qt.io> | 2017-01-11 10:39:43 +0000 |
commit | 1636f3bc9294cb3f3612bcc02bd3be305fb3f707 (patch) | |
tree | 20592ba3ab05cbd30f9582edbb7c6c09958ddc01 /src/network/access/qhttpnetworkconnectionchannel.cpp | |
parent | 6f504a1cdd1c076365e7916f0851c5d35a8f7ad1 (diff) |
HTTP/2 - fix handling of GOAWAY frame
- Fix the case when we erroneously handled stream ID == 0 in a GOAWAY frame as
an invalid stream ID.
- _q_receivedReply: convert do{}while() loop into to while(){} to prevent
it from handling any frames after GOAWAY frame received and all active frame
finished.
- sendRequest - if we received GOAWAY, also clear spdyRequests in the connection
channel, otherwise it keeps re-trying to send requests!
- Http network connection channel never resets a protocolHandler in _q_encrypted/
_q_connected, which is BAD for HTTP/2, since HTTP/2 has unique per-connection
compression context and must be reset - now we recreate the protocol handler in
_q_encrypted or _q_connected (https/http).
- Update autotest.
Task-number: QTBUG-57600
Change-Id: Ib864ce52287bab23334ff43a83ba4b0b7cb52c60
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/network/access/qhttpnetworkconnectionchannel.cpp')
-rw-r--r-- | src/network/access/qhttpnetworkconnectionchannel.cpp | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 205490b830..646ede0022 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -180,9 +180,7 @@ void QHttpNetworkConnectionChannel::init() sslSocket->setSslConfiguration(sslConfiguration); } else { #endif // !QT_NO_SSL - if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) - protocolHandler.reset(new QHttp2ProtocolHandler(this)); - else + if (connection->connectionType() != QHttpNetworkConnection::ConnectionTypeHTTP2) protocolHandler.reset(new QHttpProtocolHandler(this)); #ifndef QT_NO_SSL } @@ -839,6 +837,9 @@ void QHttpNetworkConnectionChannel::_q_connected() } else { state = QHttpNetworkConnectionChannel::IdleState; if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) { + // We have to reset QHttp2ProtocolHandler's state machine, it's a new + // connection and the handler's state is unique per connection. + protocolHandler.reset(new QHttp2ProtocolHandler(this)); if (spdyRequestsToSend.count() > 0) { // wait for data from the server first (e.g. initial window, max concurrent requests) QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); @@ -1092,6 +1093,10 @@ void QHttpNetworkConnectionChannel::_q_encrypted() emitFinishedWithError(QNetworkReply::SslHandshakeFailedError, "detected unknown Next Protocol Negotiation protocol"); } + } else if (connection->connectionType() == QHttpNetworkConnection::ConnectionTypeHTTP2) { + // We have to reset QHttp2ProtocolHandler's state machine, it's a new + // connection and the handler's state is unique per connection. + protocolHandler.reset(new QHttp2ProtocolHandler(this)); } if (!socket) |