From 603eaa9fbb250ce1f4ec5a5a9750a115ef08a956 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 6 Apr 2020 11:12:55 +0200 Subject: [PATCH] H2C - make sure we send the client preface and settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's required as a response to upgraded protocol and apparently some servers would wait for it, not sending any frames. Becomes a problem in case only one request was sent. Fixes: QTBUG-83312 Change-Id: I90dc5c04095f0b78baa404466625d329dc4c6e21 Reviewed-by: MÃ¥rten Nordheim --- src/network/access/qhttp2protocolhandler.cpp | 6 ++++++ src/network/access/qhttp2protocolhandler_p.h | 1 + src/network/access/qhttpnetworkconnectionchannel.cpp | 3 +++ 3 files changed, 10 insertions(+) diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index dce51d4fd5..03f7261275 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -220,6 +220,12 @@ void QHttp2ProtocolHandler::handleConnectionClosure() goingAway = true; } +void QHttp2ProtocolHandler::ensureClientPrefaceSent() +{ + if (!prefaceSent) + sendClientPreface(); +} + void QHttp2ProtocolHandler::_q_uploadDataReadyRead() { if (!sender()) // QueuedConnection, firing after sender (byte device) was deleted. diff --git a/src/network/access/qhttp2protocolhandler_p.h b/src/network/access/qhttp2protocolhandler_p.h index 43fdb136cd..14deabd70b 100644 --- a/src/network/access/qhttp2protocolhandler_p.h +++ b/src/network/access/qhttp2protocolhandler_p.h @@ -93,6 +93,7 @@ public: QHttp2ProtocolHandler &operator = (QHttp2ProtocolHandler &&rhs) = delete; Q_INVOKABLE void handleConnectionClosure(); + Q_INVOKABLE void ensureClientPrefaceSent(); private slots: void _q_uploadDataReadyRead(); diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 319c4953b1..95850efe36 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -488,6 +488,9 @@ void QHttpNetworkConnectionChannel::allDone() QHttp2ProtocolHandler *h2c = static_cast(protocolHandler.data()); QMetaObject::invokeMethod(h2c, "_q_receiveReply", Qt::QueuedConnection); QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection); + // If we only had one request sent with H2 allowed, we may fail to send + // a client preface and SETTINGS, which is required by RFC 7540, 3.2. + QMetaObject::invokeMethod(h2c, "ensureClientPrefaceSent", Qt::QueuedConnection); return; } else { // Ok, whatever happened, we do not try HTTP/2 anymore ...