diff options
Diffstat (limited to 'tests/auto/network')
-rw-r--r-- | tests/auto/network/access/http2/http2srv.cpp | 28 | ||||
-rw-r--r-- | tests/auto/network/access/http2/http2srv.h | 5 | ||||
-rw-r--r-- | tests/auto/network/access/http2/tst_http2.cpp | 47 | ||||
-rw-r--r-- | tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 14 |
4 files changed, 82 insertions, 12 deletions
diff --git a/tests/auto/network/access/http2/http2srv.cpp b/tests/auto/network/access/http2/http2srv.cpp index 69e480b164..b0bae13bad 100644 --- a/tests/auto/network/access/http2/http2srv.cpp +++ b/tests/auto/network/access/http2/http2srv.cpp @@ -123,6 +123,12 @@ void Http2Server::emulateGOAWAY(int timeout) goawayTimeout = timeout; } +void Http2Server::redirectOpenStream(quint16 port) +{ + redirectWhileReading = true; + targetPort = port; +} + void Http2Server::startServer() { #ifdef QT_NO_SSL @@ -775,7 +781,19 @@ void Http2Server::sendResponse(quint32 streamID, bool emptyBody) if (emptyBody) writer.addFlag(FrameFlag::END_STREAM); - HttpHeader header = {{":status", "200"}}; + HttpHeader header; + if (redirectWhileReading) { + qDebug("server received HEADERS frame (followed by DATA frames), redirecting ..."); + Q_ASSERT(targetPort); + header.push_back({":status", "308"}); + const QString url("%1://localhost:%2/"); + header.push_back({"location", url.arg(clearTextHTTP2 ? QStringLiteral("http") : QStringLiteral("https"), + QString::number(targetPort)).toLatin1()}); + + } else { + header.push_back({":status", "200"}); + } + if (!emptyBody) { header.push_back(HPack::HeaderField("content-length", QString("%1").arg(responseBody.size()).toLatin1())); @@ -871,7 +889,13 @@ void Http2Server::processRequest() activeRequests[streamID] = decoder.decodedHeader(); if (headersFrame.flags().testFlag(FrameFlag::END_STREAM)) emit receivedRequest(streamID); - // else - we're waiting for incoming DATA frames ... + + if (redirectWhileReading) { + sendResponse(streamID, true); + // Don't try to read any DATA frames ... + socket->disconnect(); + } // else - we're waiting for incoming DATA frames ... + continuedRequest.clear(); } diff --git a/tests/auto/network/access/http2/http2srv.h b/tests/auto/network/access/http2/http2srv.h index 76c5a0ee36..14b41cc67d 100644 --- a/tests/auto/network/access/http2/http2srv.h +++ b/tests/auto/network/access/http2/http2srv.h @@ -74,6 +74,7 @@ public: void enablePushPromise(bool enabled, const QByteArray &path = QByteArray()); void setResponseBody(const QByteArray &body); void emulateGOAWAY(int timeout); + void redirectOpenStream(quint16 targetPort); // Invokables, since we can call them from the main thread, // but server (can) work on its own thread. @@ -186,6 +187,10 @@ private: // We need it for PUSH_PROMISE, with the correct port number appended, // when replying to essentially 1.1 request. QByteArray authority; + // Redirect, with status code 308, as soon as we've seen headers, while client + // may still be sending DATA frames. See tst_Http2::earlyResponse(). + bool redirectWhileReading = false; + quint16 targetPort = 0; 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 51e1849512..ecf4c5814a 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -74,6 +74,7 @@ private slots: void pushPromise(); void goaway_data(); void goaway(); + void earlyResponse(); protected slots: // Slots to listen to our in-process server: @@ -439,6 +440,47 @@ void tst_Http2::goaway() QVERIFY(!serverGotSettingsACK); } +void tst_Http2::earlyResponse() +{ + // In this test we'd like to verify client side can handle HEADERS frame while + // its stream is in 'open' state. To achieve this, we send a POST request + // with some payload, so that the client is first sending HEADERS and then + // DATA frames without END_STREAM flag set yet (thus the stream is in Stream::open + // state). Upon receiving the client's HEADERS frame our server ('redirector') + // immediately (without trying to read any DATA frames) responds with status + // code 308. The client should properly handle this. + + clearHTTP2State(); + + serverPort = 0; + nRequests = 1; + + ServerPtr targetServer(newServer(defaultServerSettings)); + + QMetaObject::invokeMethod(targetServer.data(), "startServer", Qt::QueuedConnection); + runEventLoop(); + + QVERIFY(serverPort != 0); + + const quint16 targetPort = serverPort; + serverPort = 0; + + ServerPtr redirector(newServer(defaultServerSettings)); + redirector->redirectOpenStream(targetPort); + + QMetaObject::invokeMethod(redirector.data(), "startServer", Qt::QueuedConnection); + runEventLoop(); + + QVERIFY(serverPort); + sendRequest(1, QNetworkRequest::NormalPriority, {10000000, Qt::Uninitialized}); + + runEventLoop(); + + QVERIFY(nRequests == 0); + QVERIFY(prefaceOK); + QVERIFY(serverGotSettingsACK); +} + void tst_Http2::serverStarted(quint16 port) { serverPort = port; @@ -500,6 +542,7 @@ void tst_Http2::sendRequest(int streamNumber, QNetworkRequest request(url); request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, QVariant(true)); + request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, QVariant(true)); request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain")); request.setPriority(priority); @@ -592,6 +635,10 @@ void tst_Http2::replyFinished() const QVariant spdyUsed(reply->attribute(QNetworkRequest::SpdyWasUsedAttribute)); QVERIFY(spdyUsed.isValid()); QVERIFY(!spdyUsed.toBool()); + const QVariant code(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute)); + QVERIFY(code.isValid()); + QVERIFY(code.canConvert<int>()); + QCOMPARE(code.value<int>(), 200); } --nRequests; diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 1332b369e7..bb01116240 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -1188,13 +1188,7 @@ void tst_QSslSocket::protocolServerSide_data() #if !defined(OPENSSL_NO_SSL2) // OpenSSL 1.1 has removed SSL2 support. But there is no OPENSSL_NO_SSL2 macro ... #define OPENSSL_NO_SSL2 -#endif - // A client using our OpenSSL1.1 backend will negotiate up from TLS 1.0 or 1.1 - // to TLS 1.2 if the server asks for it, where our older backend fails to compromise. - // So some tests that fail for the old pass with the new. - const bool willUseTLS12 = true; -#else - const bool willUseTLS12 = false; +#endif // OPENSSL_NO_SSL2 #endif // opensslv11 #if !defined(OPENSSL_NO_SSL2) && !defined(QT_SECURETRANSPORT) @@ -1290,7 +1284,7 @@ void tst_QSslSocket::protocolServerSide_data() QTest::newRow("tls1.1orlater-ssl3") << QSsl::TlsV1_1OrLater << QSsl::SslV3 << false; #endif - QTest::newRow("tls1.1orlater-tls1.0") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_0 << willUseTLS12; + QTest::newRow("tls1.1orlater-tls1.0") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_0 << false; QTest::newRow("tls1.1orlater-tls1.1") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_1 << true; QTest::newRow("tls1.1orlater-tls1.2") << QSsl::TlsV1_1OrLater << QSsl::TlsV1_2 << true; @@ -1300,8 +1294,8 @@ void tst_QSslSocket::protocolServerSide_data() #if !defined(OPENSSL_NO_SSL3) QTest::newRow("tls1.2orlater-ssl3") << QSsl::TlsV1_2OrLater << QSsl::SslV3 << false; #endif - QTest::newRow("tls1.2orlater-tls1.0") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_0 << willUseTLS12; - QTest::newRow("tls1.2orlater-tls1.1") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_1 << willUseTLS12; + QTest::newRow("tls1.2orlater-tls1.0") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_0 << false; + QTest::newRow("tls1.2orlater-tls1.1") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_1 << false; QTest::newRow("tls1.2orlater-tls1.2") << QSsl::TlsV1_2OrLater << QSsl::TlsV1_2 << true; QTest::newRow("any-tls1.0") << QSsl::AnyProtocol << QSsl::TlsV1_0 << true; |