summaryrefslogtreecommitdiffstats
path: root/tests/auto/network/access/http2
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@qt.io>2019-08-20 12:09:42 +0200
committerTimur Pocheptsov <timur.pocheptsov@qt.io>2019-08-22 15:36:22 +0200
commit8d302aea33d54d7930fc700ab44a55e058d7bfcc (patch)
tree11df6cf5b6fd81e5b03ca59978d785b6672da52a /tests/auto/network/access/http2
parentd55712153a357cc5cc975bf599470619b7c77faa (diff)
HTTP/2: use a non-default MAX_FRAME_SIZE
And send it in our 'SETTINGS' frame. Add an auto-test for this and (as a bonus) - fix a bug accidentally introduced by the previous change. Task-number: QTBUG-77412 Change-Id: I4277ff47e8d8d3b6b8666fbcd7dc73c827f349c0 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'tests/auto/network/access/http2')
-rw-r--r--tests/auto/network/access/http2/http2srv.cpp6
-rw-r--r--tests/auto/network/access/http2/http2srv.h1
-rw-r--r--tests/auto/network/access/http2/tst_http2.cpp70
3 files changed, 76 insertions, 1 deletions
diff --git a/tests/auto/network/access/http2/http2srv.cpp b/tests/auto/network/access/http2/http2srv.cpp
index 1ddb6aa77d..a8eebf5a24 100644
--- a/tests/auto/network/access/http2/http2srv.cpp
+++ b/tests/auto/network/access/http2/http2srv.cpp
@@ -218,7 +218,7 @@ void Http2Server::sendDATA(quint32 streamID, quint32 windowSize)
quint32 bytesToSend = std::min<quint32>(windowSize, responseBody.size() - offset);
quint32 bytesSent = 0;
- const quint32 frameSizeLimit(clientSetting(Settings::MAX_FRAME_SIZE_ID, Http2::maxPayloadSize));
+ const quint32 frameSizeLimit(clientSetting(Settings::MAX_FRAME_SIZE_ID, Http2::minPayloadLimit));
const uchar *src = reinterpret_cast<const uchar *>(responseBody.constData() + offset);
const bool last = offset + bytesToSend == quint32(responseBody.size());
@@ -236,6 +236,10 @@ void Http2Server::sendDATA(quint32 streamID, quint32 windowSize)
src += chunkSize;
bytesToSend -= chunkSize;
bytesSent += chunkSize;
+ if (frameSizeLimit != Http2::minPayloadLimit) {
+ // Our test is probably interested in how many DATA frames were sent.
+ emit sendingData();
+ }
}
if (interrupted.loadAcquire())
diff --git a/tests/auto/network/access/http2/http2srv.h b/tests/auto/network/access/http2/http2srv.h
index 9cb846b0b3..3105684d59 100644
--- a/tests/auto/network/access/http2/http2srv.h
+++ b/tests/auto/network/access/http2/http2srv.h
@@ -128,6 +128,7 @@ Q_SIGNALS:
void receivedRequest(quint32 streamID);
void receivedData(quint32 streamID);
void windowUpdate(quint32 streamID);
+ void sendingData();
private slots:
void connectionEstablished();
diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp
index 6a0dc6db02..e24a06bc34 100644
--- a/tests/auto/network/access/http2/tst_http2.cpp
+++ b/tests/auto/network/access/http2/tst_http2.cpp
@@ -82,6 +82,8 @@ RawSettings qt_H2ConfigurationToSettings(const QHttp2Configuration &config = qt_
RawSettings settings;
settings[Http2::Settings::ENABLE_PUSH_ID] = config.serverPushEnabled();
settings[Http2::Settings::INITIAL_WINDOW_SIZE_ID] = config.streamReceiveWindowSize();
+ if (config.maxFrameSize() != Http2::minPayloadLimit)
+ settings[Http2::Settings::MAX_FRAME_SIZE_ID] = config.maxFrameSize();
return settings;
}
@@ -107,6 +109,7 @@ private slots:
void earlyResponse();
void connectToHost_data();
void connectToHost();
+ void maxFrameSize();
protected slots:
// Slots to listen to our in-process server:
@@ -696,6 +699,73 @@ void tst_Http2::connectToHost()
QVERIFY(reply->isFinished());
}
+void tst_Http2::maxFrameSize()
+{
+#if !QT_CONFIG(ssl)
+ QSKIP("TLS support is needed for this test");
+#endif // QT_CONFIG(ssl)
+
+ // Here we test we send 'MAX_FRAME_SIZE' setting in our
+ // 'SETTINGS'. If done properly, our server will not chunk
+ // the payload into several DATA frames.
+
+#if QT_CONFIG(securetransport)
+ // Normally on macOS we use plain text only for SecureTransport
+ // does not support ALPN on the server side. With 'direct encrytped'
+ // we have to use TLS sockets (== private key) and thus suppress a
+ // keychain UI asking for permission to use a private key.
+ // Our CI has this, but somebody testing locally - will have a problem.
+ qputenv("QT_SSL_USE_TEMPORARY_KEYCHAIN", QByteArray("1"));
+ auto envRollback = qScopeGuard([](){
+ qunsetenv("QT_SSL_USE_TEMPORARY_KEYCHAIN");
+ });
+#endif // QT_CONFIG(securetransport)
+
+ auto connectionType = H2Type::h2Alpn;
+ auto attribute = QNetworkRequest::HTTP2AllowedAttribute;
+ if (clearTextHTTP2) {
+ connectionType = H2Type::h2Direct;
+ attribute = QNetworkRequest::Http2DirectAttribute;
+ }
+
+ auto h2Config = qt_defaultH2Configuration();
+ h2Config.setMaxFrameSize(Http2::minPayloadLimit * 3);
+
+ serverPort = 0;
+ nRequests = 1;
+
+ ServerPtr srv(newServer(defaultServerSettings, connectionType,
+ qt_H2ConfigurationToSettings(h2Config)));
+ srv->setResponseBody(QByteArray(Http2::minPayloadLimit * 2, 'q'));
+ QMetaObject::invokeMethod(srv.data(), "startServer", Qt::QueuedConnection);
+ runEventLoop();
+ QVERIFY(serverPort != 0);
+
+ const QSignalSpy frameCounter(srv.data(), &Http2Server::sendingData);
+ auto url = requestUrl(connectionType);
+ url.setPath(QString("/stream1.html"));
+
+ QNetworkRequest request(url);
+ request.setAttribute(attribute, QVariant(true));
+ request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain"));
+ request.setHttp2Configuration(h2Config);
+
+ QNetworkReply *reply = manager->get(request);
+ reply->ignoreSslErrors();
+ connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
+
+ runEventLoop();
+ STOP_ON_FAILURE
+
+ // Normally, with a 16kb limit, our server would split such
+ // a response into 3 'DATA' frames (16kb + 16kb + 0|END_STREAM).
+ QCOMPARE(frameCounter.count(), 1);
+
+ QVERIFY(nRequests == 0);
+ QVERIFY(prefaceOK);
+ QVERIFY(serverGotSettingsACK);
+}
+
void tst_Http2::serverStarted(quint16 port)
{
serverPort = port;