summaryrefslogtreecommitdiffstats
path: root/tests/auto/network/access
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2020-05-07 15:20:55 +0200
committerMårten Nordheim <marten.nordheim@qt.io>2020-05-13 13:54:44 +0200
commit80e0d0e08eaccf032c4a42ce7c5d3ffb91837141 (patch)
tree8b9acabac005e0abeab1f519cb94c477ccc74e24 /tests/auto/network/access
parentb35551a75e37d4ae1ddb024a82c67cdba714879a (diff)
QNetworkReply/http2: Add a contentEncoding test
Will be useful when DecompressHelper gets taken into use for both. Task-number: QTBUG-83269 Change-Id: Iaf253219bed193025c2b82d6609f4dcc4de33df8 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'tests/auto/network/access')
-rw-r--r--tests/auto/network/access/http2/http2srv.cpp8
-rw-r--r--tests/auto/network/access/http2/http2srv.h4
-rw-r--r--tests/auto/network/access/http2/tst_http2.cpp106
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp55
4 files changed, 173 insertions, 0 deletions
diff --git a/tests/auto/network/access/http2/http2srv.cpp b/tests/auto/network/access/http2/http2srv.cpp
index a8eebf5a24..9513744476 100644
--- a/tests/auto/network/access/http2/http2srv.cpp
+++ b/tests/auto/network/access/http2/http2srv.cpp
@@ -120,6 +120,11 @@ void Http2Server::setResponseBody(const QByteArray &body)
responseBody = body;
}
+void Http2Server::setContentEncoding(const QByteArray &encoding)
+{
+ contentEncoding = encoding;
+}
+
void Http2Server::emulateGOAWAY(int timeout)
{
Q_ASSERT(timeout >= 0);
@@ -841,6 +846,9 @@ void Http2Server::sendResponse(quint32 streamID, bool emptyBody)
QString("%1").arg(responseBody.size()).toLatin1()));
}
+ if (!contentEncoding.isEmpty())
+ header.push_back(HPack::HeaderField("content-encoding", contentEncoding));
+
HPack::BitOStream ostream(writer.outboundFrame().buffer);
const bool result = encoder.encodeResponse(ostream, header);
Q_ASSERT(result);
diff --git a/tests/auto/network/access/http2/http2srv.h b/tests/auto/network/access/http2/http2srv.h
index 3105684d59..baf0155988 100644
--- a/tests/auto/network/access/http2/http2srv.h
+++ b/tests/auto/network/access/http2/http2srv.h
@@ -86,6 +86,8 @@ public:
// To be called before server started:
void enablePushPromise(bool enabled, const QByteArray &path = QByteArray());
void setResponseBody(const QByteArray &body);
+ // No content encoding is actually performed, call setResponseBody with already encoded data
+ void setContentEncoding(const QByteArray &contentEncoding);
void emulateGOAWAY(int timeout);
void redirectOpenStream(quint16 targetPort);
@@ -211,6 +213,8 @@ private:
bool redirectSent = false;
quint16 targetPort = 0;
QAtomicInt interrupted;
+
+ QByteArray contentEncoding;
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 a92c948ade..5a250c6226 100644
--- a/tests/auto/network/access/http2/tst_http2.cpp
+++ b/tests/auto/network/access/http2/tst_http2.cpp
@@ -111,6 +111,9 @@ private slots:
void connectToHost();
void maxFrameSize();
+ void contentEncoding_data();
+ void contentEncoding();
+
protected slots:
// Slots to listen to our in-process server:
void serverStarted(quint16 port);
@@ -767,6 +770,109 @@ void tst_Http2::maxFrameSize()
QVERIFY(serverGotSettingsACK);
}
+void tst_Http2::contentEncoding_data()
+{
+ QTest::addColumn<QByteArray>("encoding");
+ QTest::addColumn<QByteArray>("body");
+ QTest::addColumn<QByteArray>("expected");
+ QTest::addColumn<QNetworkRequest::Attribute>("h2Attribute");
+ QTest::addColumn<H2Type>("connectionType");
+
+ struct ContentEncodingData
+ {
+ ContentEncodingData(QByteArray &&ce, QByteArray &&body, QByteArray &&ex)
+ : contentEncoding(ce), body(body), expected(ex)
+ {
+ }
+ QByteArray contentEncoding;
+ QByteArray body;
+ QByteArray expected;
+ };
+
+ QVector<ContentEncodingData> contentEncodingData;
+ contentEncodingData.emplace_back(
+ "gzip", QByteArray::fromBase64("H4sIAAAAAAAAA8tIzcnJVyjPL8pJAQCFEUoNCwAAAA=="),
+ "hello world");
+ contentEncodingData.emplace_back(
+ "deflate", QByteArray::fromBase64("eJzLSM3JyVcozy/KSQEAGgsEXQ=="), "hello world");
+
+ // Loop through and add the data...
+ for (const auto &data : contentEncodingData) {
+ const char *name = data.contentEncoding.data();
+ QTest::addRow("%s-h2c-upgrade", name)
+ << data.contentEncoding << data.body << data.expected
+ << QNetworkRequest::Http2AllowedAttribute << H2Type::h2c;
+ QTest::addRow("%s-h2c-direct", name)
+ << data.contentEncoding << data.body << data.expected
+ << QNetworkRequest::Http2DirectAttribute << H2Type::h2cDirect;
+
+ if (!clearTextHTTP2)
+ QTest::addRow("%s-h2-ALPN", name)
+ << data.contentEncoding << data.body << data.expected
+ << QNetworkRequest::Http2AllowedAttribute << H2Type::h2Alpn;
+
+#if QT_CONFIG(ssl)
+ QTest::addRow("%s-h2-direct", name)
+ << data.contentEncoding << data.body << data.expected
+ << QNetworkRequest::Http2DirectAttribute << H2Type::h2Direct;
+#endif
+ }
+}
+
+void tst_Http2::contentEncoding()
+{
+ clearHTTP2State();
+
+#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
+
+ QFETCH(H2Type, connectionType);
+
+ ServerPtr targetServer(newServer(defaultServerSettings, connectionType));
+ QFETCH(QByteArray, body);
+ targetServer->setResponseBody(body);
+ QFETCH(QByteArray, encoding);
+ targetServer->setContentEncoding(encoding);
+
+ QMetaObject::invokeMethod(targetServer.data(), "startServer", Qt::QueuedConnection);
+ runEventLoop();
+
+ QVERIFY(serverPort != 0);
+
+ nRequests = 1;
+
+ auto url = requestUrl(connectionType);
+ url.setPath("/index.html");
+
+ QNetworkRequest request(url);
+ QFETCH(const QNetworkRequest::Attribute, h2Attribute);
+ request.setAttribute(h2Attribute, QVariant(true));
+
+ auto reply = manager->get(request);
+ connect(reply, &QNetworkReply::finished, this, &tst_Http2::replyFinished);
+ // Since we're using self-signed certificates,
+ // ignore SSL errors:
+ reply->ignoreSslErrors();
+
+ runEventLoop();
+ STOP_ON_FAILURE
+
+ QVERIFY(nRequests == 0);
+ QVERIFY(prefaceOK);
+ QVERIFY(serverGotSettingsACK);
+
+ QCOMPARE(reply->error(), QNetworkReply::NoError);
+ QVERIFY(reply->isFinished());
+ QTEST(reply->readAll(), "expected");
+}
+
void tst_Http2::serverStarted(quint16 port)
{
serverPort = port;
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 915926e488..2f1e97f853 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -503,6 +503,10 @@ private Q_SLOTS:
void getWithTimeout();
void postWithTimeout();
+
+ void contentEncoding_data();
+ void contentEncoding();
+
// NOTE: This test must be last!
void parentingRepliesToTheApp();
private:
@@ -9175,6 +9179,57 @@ void tst_QNetworkReply::postWithTimeout()
manager.setTransferTimeout(0);
}
+void tst_QNetworkReply::contentEncoding_data()
+{
+ QTest::addColumn<QByteArray>("encoding");
+ QTest::addColumn<QByteArray>("body");
+ QTest::addColumn<QByteArray>("expected");
+
+ QTest::newRow("gzip-hello-world")
+ << QByteArray("gzip")
+ << QByteArray::fromBase64("H4sIAAAAAAAAA8tIzcnJVyjPL8pJAQCFEUoNCwAAAA==")
+ << QByteArray("hello world");
+ QTest::newRow("deflate-hello-world")
+ << QByteArray("deflate") << QByteArray::fromBase64("eJzLSM3JyVcozy/KSQEAGgsEXQ==")
+ << QByteArray("hello world");
+}
+
+void tst_QNetworkReply::contentEncoding()
+{
+ QFETCH(QByteArray, encoding);
+ QFETCH(QByteArray, body);
+ QString header("HTTP/1.0 200 OK\r\nContent-Encoding: %1\r\nContent-Length: %2\r\n\r\n");
+ header = header.arg(encoding, QString::number(body.size()));
+
+ MiniHttpServer server(header.toLatin1() + body);
+
+ QNetworkRequest request(QUrl("http://localhost:" + QString::number(server.serverPort())));
+ QNetworkReplyPtr reply(manager.get(request));
+
+ QVERIFY2(waitForFinish(reply) == Success, msgWaitForFinished(reply));
+ QCOMPARE(reply->error(), QNetworkReply::NoError);
+
+ {
+ // Check that we included the content encoding method in our Accept-Encoding header
+ const QByteArray &receivedData = server.receivedData;
+ int start = receivedData.indexOf("Accept-Encoding");
+ QVERIFY(start != -1);
+ int end = receivedData.indexOf("\r\n", start);
+ QVERIFY(end != -1);
+ QByteArray acceptedEncoding = receivedData.mid(start, end - start);
+ acceptedEncoding = acceptedEncoding.mid(acceptedEncoding.indexOf(':') + 1).trimmed();
+ QByteArrayList list = acceptedEncoding.split(',');
+ for (QByteArray &encoding : list)
+ encoding = encoding.trimmed();
+ QVERIFY2(list.contains(encoding), acceptedEncoding.data());
+ }
+
+ QFETCH(QByteArray, expected);
+
+ QCOMPARE(reply->bytesAvailable(), expected.size());
+ QCOMPARE(reply->readAll(), expected);
+}
+
// NOTE: This test must be last testcase in tst_qnetworkreply!
void tst_QNetworkReply::parentingRepliesToTheApp()
{