From 306ebe03ea13c6e0ac8de46e46d0859384954567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A5rten=20Nordheim?= Date: Fri, 12 Jun 2020 15:37:06 +0200 Subject: 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 --- src/network/access/qnetworkreplyhttpimpl.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'src/network/access/qnetworkreplyhttpimpl.cpp') diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index e591340257..f189f5be20 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1155,6 +1155,26 @@ void QNetworkReplyHttpImplPrivate::onRedirected(const QUrl &redirectUrl, int htt redirectRequest = createRedirectRequest(originalRequest, url, maxRedirectsRemaining); operation = getRedirectOperation(operation, httpStatus); + // Clear stale headers, the relevant ones get set again later + httpRequest.clearHeaders(); + if (operation == QNetworkAccessManager::GetOperation + || operation == QNetworkAccessManager::HeadOperation) { + // possibly changed from not-GET/HEAD to GET/HEAD, make sure to get rid of upload device + uploadByteDevice.reset(); + uploadByteDevicePosition = 0; + if (outgoingData) { + QObject::disconnect(outgoingData, SIGNAL(readyRead()), q, + SLOT(_q_bufferOutgoingData())); + QObject::disconnect(outgoingData, SIGNAL(readChannelFinished()), q, + SLOT(_q_bufferOutgoingDataFinished())); + } + outgoingData = nullptr; + outgoingDataBuffer.reset(); + // We need to explicitly unset these headers so they're not reapplied to the httpRequest + redirectRequest.setHeader(QNetworkRequest::ContentLengthHeader, QVariant()); + redirectRequest.setHeader(QNetworkRequest::ContentTypeHeader, QVariant()); + } + if (const QNetworkCookieJar *const cookieJar = manager->cookieJar()) { auto cookies = cookieJar->cookiesForUrl(url); if (!cookies.empty()) { @@ -1435,6 +1455,9 @@ void QNetworkReplyHttpImplPrivate::resetUploadDataSlot(bool *r) // Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread void QNetworkReplyHttpImplPrivate::sentUploadDataSlot(qint64 pos, qint64 amount) { + if (!uploadByteDevice) // uploadByteDevice is no longer available + return; + if (uploadByteDevicePosition + amount != pos) { // Sanity check, should not happen. error(QNetworkReply::UnknownNetworkError, QString()); @@ -1449,6 +1472,9 @@ void QNetworkReplyHttpImplPrivate::wantUploadDataSlot(qint64 maxSize) { Q_Q(QNetworkReplyHttpImpl); + if (!uploadByteDevice) // uploadByteDevice is no longer available + return; + // call readPointer qint64 currentUploadDataLength = 0; char *data = const_cast(uploadByteDevice->readPointer(maxSize, currentUploadDataLength)); -- cgit v1.2.3