summaryrefslogtreecommitdiffstats
path: root/tests/auto/network/access
diff options
context:
space:
mode:
authorMårten Nordheim <marten.nordheim@qt.io>2020-06-12 15:37:06 +0200
committerMårten Nordheim <marten.nordheim@qt.io>2020-06-12 16:11:55 +0200
commit306ebe03ea13c6e0ac8de46e46d0859384954567 (patch)
tree6081ea0ed3b52806e9c88853d3330f882c745ef6 /tests/auto/network/access
parent76228da096d0b1defd6148d6f75e1a57e8c9f65b (diff)
Http: Fix POST-to-GET redirects still uploading or transmitting CL
CL = Content-Length The uploadByteDevice was kept after a redirect which caused the internals to assume that we had to upload the data. Even if this was not the case we still transmitted the Content-Length header from the first request which was now stored in two places. Fixes: QTBUG-84162 Pick-to: 5.15 Change-Id: Ic86b1ef0766ffcc50beeed96c1c915b721d40209 Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'tests/auto/network/access')
-rw-r--r--tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp74
1 files changed, 73 insertions, 1 deletions
diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
index 2f1e97f853..aeb5c367da 100644
--- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
+++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
@@ -492,6 +492,8 @@ private Q_SLOTS:
void ioHttpRedirectMultipartPost();
void ioHttpRedirectDelete();
void ioHttpRedirectCustom();
+ void ioHttpRedirectWithUploadDevice_data();
+ void ioHttpRedirectWithUploadDevice();
#ifndef QT_NO_SSL
void putWithServerClosingConnectionImmediately();
#endif
@@ -715,7 +717,8 @@ public slots:
if (doubleEndlPos != -1) {
const int endOfHeader = doubleEndlPos + 4;
- hasContent = receivedData.startsWith("POST") || receivedData.startsWith("PUT");
+ hasContent = receivedData.startsWith("POST") || receivedData.startsWith("PUT")
+ || receivedData.startsWith("CUSTOM_WITH_PAYLOAD");
if (hasContent && contentLength == 0)
parseContentLength();
contentRead = receivedData.length() - endOfHeader;
@@ -8780,6 +8783,75 @@ void tst_QNetworkReply::ioHttpRedirectCustom()
QVERIFY2(target.receivedData.startsWith("CUSTOM"), "Target server called with the wrong method");
}
+void tst_QNetworkReply::ioHttpRedirectWithUploadDevice_data()
+{
+ QTest::addColumn<QByteArray>("method");
+ QTest::addColumn<QString>("status");
+ QTest::addColumn<bool>("keepMethod");
+
+ QTest::addRow("post-301") << QByteArray("POST") << "301 Moved Permanently" << false;
+ QTest::addRow("post-307") << QByteArray("POST") << "307 Temporary Redirect" << true;
+
+ const QByteArray customVerb = QByteArray("CUSTOM_WITH_PAYLOAD");
+ QTest::addRow("custom-301") << customVerb << "301 Moved Permanently" << false;
+ QTest::addRow("custom-307") << customVerb << "307 Temporary Redirect" << true;
+}
+
+/*
+ Tests that we properly disregard the upload device when redirecting
+ and changing method to GET, and that it gets reset properly when
+ redirecting (without changing method) for POST and a custom method.
+*/
+void tst_QNetworkReply::ioHttpRedirectWithUploadDevice()
+{
+ QFETCH(QByteArray, method);
+ QFETCH(QString, status);
+ QFETCH(bool, keepMethod);
+
+ MiniHttpServer target(httpEmpty200Response, false);
+ QUrl targetUrl("http://localhost/");
+ targetUrl.setPort(target.serverPort());
+
+ QString redirectReply = QStringLiteral("HTTP/1.1 %1\r\n"
+ "Content-Type: text/plain\r\n"
+ "location: %2\r\n"
+ "\r\n").arg(status, targetUrl.toString());
+ MiniHttpServer redirectServer(redirectReply.toLatin1());
+ QUrl url("http://localhost/");
+ url.setPort(redirectServer.serverPort());
+
+ QNetworkRequest request(url);
+ request.setHeader(QNetworkRequest::ContentTypeHeader, QByteArray("text/plain"));
+ auto oldRedirectPolicy = manager.redirectPolicy();
+ manager.setRedirectPolicy(QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy);
+
+ QByteArray data = "Hello world";
+ QBuffer buffer(&data);
+
+ QNetworkReplyPtr reply;
+ if (method == "POST")
+ reply.reset(manager.post(request, &buffer));
+ else
+ reply.reset(manager.sendCustomRequest(request, method, &buffer));
+ // Restore previous policy:
+ manager.setRedirectPolicy(oldRedirectPolicy);
+
+ QCOMPARE(waitForFinish(reply), int(Success));
+ QByteArray expectedMethod = method;
+ if (!keepMethod)
+ expectedMethod = "GET";
+ QVERIFY2(target.receivedData.startsWith(expectedMethod), "Target server called with the wrong method");
+ if (keepMethod) { // keepMethod also means we resend the data
+ QVERIFY2(target.receivedData.endsWith(data), "Target server didn't receive the data");
+ } else {
+ // we shouldn't send Content-Length with not content (esp. for GET)
+ QVERIFY2(!target.receivedData.contains("Content-Length"),
+ "Target server should not have received a Content-Length header");
+ QVERIFY2(!target.receivedData.contains("Content-Type"),
+ "Target server should not have received a Content-Type header");
+ }
+}
+
#ifndef QT_NO_SSL
class PutWithServerClosingConnectionImmediatelyHandler: public QObject