diff options
author | Mårten Nordheim <marten.nordheim@qt.io> | 2022-04-21 17:32:59 +0200 |
---|---|---|
committer | Mårten Nordheim <marten.nordheim@qt.io> | 2022-04-27 18:31:01 +0200 |
commit | 41d217829cc1c34ae7c2fee92316a91a77018f00 (patch) | |
tree | ba5a648fbd58b16db01371d1a87472033dd75952 /tests/auto/network/access/qnetworkreply | |
parent | d642c16fe745e156a93129fbb3750784b361ee39 (diff) |
QHttp: Fix handling of redirect loaded from cache
In some situations when loading a redirect from cache which would lead
to a real request we would not emit the finished() signal because the
replyFinished function has a pre-condition that the response did
not originate from the cache.
However, after the initial redirect was loaded from the cache we never
unset the 'loadingFromCache' boolean, so it was still true after the
request had been made to the real target.
Pick-to: 6.2 6.3 5.15
Change-Id: I015a2ebae4af4bd17392182c3951e875a7b353c4
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'tests/auto/network/access/qnetworkreply')
-rw-r--r-- | tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index 9c177e6281..50084beb0a 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -500,6 +500,7 @@ private Q_SLOTS: void ioHttpCookiesDuringRedirect(); void ioHttpRedirect_data(); void ioHttpRedirect(); + void ioHttpRedirectWithCache(); void ioHttpRedirectFromLocalToRemote(); void ioHttpRedirectPostPut_data(); void ioHttpRedirectPostPut(); @@ -8874,6 +8875,64 @@ void tst_QNetworkReply::ioHttpRedirect() QVERIFY(validateRedirectedResponseHeaders(reply)); } +/* + Test that, if we load a redirect from cache, we don't treat the request to + the destination of the redirect as a redirect. + + If it was treated as a redirect the finished() signal was never emitted! +*/ +void tst_QNetworkReply::ioHttpRedirectWithCache() +{ + // Disallow caching the result so that the second request must also send the request + QByteArray http200ResponseNoCache = "HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + "Cache-Control: no-cache\r\n" + "\r\nHello"; + + MiniHttpServer target(http200ResponseNoCache, false); + QUrl targetUrl("http://localhost/"); + targetUrl.setPort(target.serverPort()); + + // A cache-able redirect reply + QString redirectReply = QStringLiteral("HTTP/1.1 308\r\n" + "Content-Type: text/plain\r\n" + "location: %1\r\n" + "Cache-Control: max-age=3600\r\n" + "\r\nYou're being redirected").arg(targetUrl.toString()); + MiniHttpServer redirectServer(redirectReply.toLatin1(), false); + QUrl url("http://localhost/"); + url.setPort(redirectServer.serverPort()); + + QTemporaryDir tempDir(QDir::tempPath() + "/tmp_cache_28035"); + QVERIFY2(tempDir.isValid(), qPrintable(tempDir.errorString())); + tempDir.setAutoRemove(true); + + QNetworkDiskCache *diskCache = new QNetworkDiskCache(); + diskCache->setCacheDirectory(tempDir.path()); + // Manager takes ownership of the cache: + manager.setCache(diskCache); + QCOMPARE(diskCache->cacheSize(), 0); + + // Send the first request, we end up caching the redirect reply + QNetworkRequest request(url); + QNetworkReplyPtr reply(manager.get(request)); + + QCOMPARE(waitForFinish(reply), int(Success)); + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + QVERIFY(validateRedirectedResponseHeaders(reply)); + + QVERIFY(diskCache->cacheSize() != 0); + + // Now for the second request, we will use the cache, and we test that the finished() + // signal is still emitted. + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); + reply.reset(manager.get(request)); + + QCOMPARE(waitForFinish(reply), int(Success)); + QCOMPARE(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(), 200); + QVERIFY(validateRedirectedResponseHeaders(reply)); +} + void tst_QNetworkReply::ioHttpRedirectFromLocalToRemote() { QUrl targetUrl("http://" + QtNetworkSettings::httpServerName() + "/qtest/rfc3252.txt"); |