summaryrefslogtreecommitdiffstats
path: root/tests/auto/network/access
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2023-03-06 16:23:23 +0100
committerMårten Nordheim <marten.nordheim@qt.io>2023-04-01 00:36:58 +0200
commit7822b89aef30404164bc6f6f790d0cc563e10cbf (patch)
tree2bf61b54753c2634dacc9393f7d5d1b45f62a797 /tests/auto/network/access
parenta81ea3d11432a86d0411c9d8806607c6f3ed7573 (diff)
Http2: Don't skip checking flag for trailing HEADERS frame if PRIORITY
If the trailing frame just had PRIORITY we would early-return, though this meant we didn't check if the frame had the END_STREAM flag set, leading some requests to certain servers to hang. Fixes: QTBUG-111417 Pick-to: 6.5 6.4 6.2 Change-Id: Iac174dc5aeca30d5d19fae35f303983de9841847 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Konrad Kujawa <konrad.kujawa@qt.io>
Diffstat (limited to 'tests/auto/network/access')
-rw-r--r--tests/auto/network/access/http2/http2srv.cpp22
-rw-r--r--tests/auto/network/access/http2/http2srv.h4
-rw-r--r--tests/auto/network/access/http2/tst_http2.cpp37
3 files changed, 60 insertions, 3 deletions
diff --git a/tests/auto/network/access/http2/http2srv.cpp b/tests/auto/network/access/http2/http2srv.cpp
index bf2625876e..91d57a5caa 100644
--- a/tests/auto/network/access/http2/http2srv.cpp
+++ b/tests/auto/network/access/http2/http2srv.cpp
@@ -111,6 +111,11 @@ void Http2Server::setRedirect(const QByteArray &url, int count)
redirectCount = count;
}
+void Http2Server::setSendTrailingHEADERS(bool enable)
+{
+ sendTrailingHEADERS = enable;
+}
+
void Http2Server::emulateGOAWAY(int timeout)
{
Q_ASSERT(timeout >= 0);
@@ -248,9 +253,20 @@ void Http2Server::sendDATA(quint32 streamID, quint32 windowSize)
return;
if (last) {
- writer.start(FrameType::DATA, FrameFlag::END_STREAM, streamID);
- writer.setPayloadSize(0);
- writer.write(*socket);
+ if (sendTrailingHEADERS) {
+ writer.start(FrameType::HEADERS,
+ FrameFlag::PRIORITY | FrameFlag::END_HEADERS | FrameFlag::END_STREAM, streamID);
+ const quint32 maxFrameSize(clientSetting(Settings::MAX_FRAME_SIZE_ID,
+ Http2::maxPayloadSize));
+ // 5 bytes for PRIORITY data:
+ writer.append(quint32(0)); // streamID 0 (32-bit)
+ writer.append(quint8(0)); // + weight 0 (8-bit)
+ writer.writeHEADERS(*socket, maxFrameSize);
+ } else {
+ writer.start(FrameType::DATA, FrameFlag::END_STREAM, streamID);
+ writer.setPayloadSize(0);
+ writer.write(*socket);
+ }
suspendedStreams.erase(it);
activeRequests.erase(streamID);
diff --git a/tests/auto/network/access/http2/http2srv.h b/tests/auto/network/access/http2/http2srv.h
index e42ed8b148..cc5353c855 100644
--- a/tests/auto/network/access/http2/http2srv.h
+++ b/tests/auto/network/access/http2/http2srv.h
@@ -68,6 +68,8 @@ public:
// Set the redirect URL and count. The server will return a redirect response with the url
// 'count' amount of times
void setRedirect(const QByteArray &redirectUrl, int count);
+ // Send a trailing HEADERS frame with PRIORITY and END_STREAM flag
+ void setSendTrailingHEADERS(bool enable);
void emulateGOAWAY(int timeout);
void redirectOpenStream(quint16 targetPort);
@@ -203,6 +205,8 @@ private:
QByteArray redirectUrl;
int redirectCount = 0;
+
+ bool sendTrailingHEADERS = false;
protected slots:
void ignoreErrorSlot();
};
diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp
index 0702a03541..1b0c074a6e 100644
--- a/tests/auto/network/access/http2/tst_http2.cpp
+++ b/tests/auto/network/access/http2/tst_http2.cpp
@@ -99,6 +99,8 @@ private slots:
void redirect_data();
void redirect();
+ void trailingHEADERS();
+
protected slots:
// Slots to listen to our in-process server:
void serverStarted(quint16 port);
@@ -1280,6 +1282,41 @@ void tst_Http2::redirect()
QTRY_VERIFY(serverGotSettingsACK);
}
+void tst_Http2::trailingHEADERS()
+{
+ clearHTTP2State();
+ serverPort = 0;
+
+ ServerPtr targetServer(newServer(defaultServerSettings, defaultConnectionType()));
+ targetServer->setSendTrailingHEADERS(true);
+
+ QMetaObject::invokeMethod(targetServer.data(), "startServer", Qt::QueuedConnection);
+ runEventLoop();
+
+ QVERIFY(serverPort != 0);
+
+ nRequests = 1;
+
+ const auto url = requestUrl(defaultConnectionType());
+ QNetworkRequest request(url);
+ // H2C might be used on macOS where SecureTransport doesn't support server-side ALPN
+ request.setAttribute(QNetworkRequest::Http2CleartextAllowedAttribute, true);
+
+ std::unique_ptr<QNetworkReply> reply{ manager->get(request) };
+ connect(reply.get(), &QNetworkReply::finished, this, &tst_Http2::replyFinished);
+
+ // Since we're using self-signed certificates, ignore SSL errors:
+ reply->ignoreSslErrors();
+
+ runEventLoop();
+ STOP_ON_FAILURE
+
+ QCOMPARE(nRequests, 0);
+
+ QCOMPARE(reply->error(), QNetworkReply::NoError);
+ QTRY_VERIFY(serverGotSettingsACK);
+}
+
void tst_Http2::serverStarted(quint16 port)
{
serverPort = port;