 src/network/access/qnetworkreplyhttpimpl.cpp | 40 +++++++++++++++-------------
 src/network/access/qnetworkreplyhttpimpl_p.h |  1 +
 2 files changed, 22 insertions(+), 19 deletions(-)

diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 53bc0f5283..579408056e 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -1052,6 +1052,8 @@ void QNetworkReplyHttpImplPrivate::replyDownloadData(QByteArray d)
 {
     Q_Q(QNetworkReplyHttpImpl);
 
+    resetTransferTimeout();
+
     // If we're closed just ignore this data
     if (!q->isOpen())
         return;
@@ -1080,7 +1082,6 @@ void QNetworkReplyHttpImplPrivate::replyDownloadData(QByteArray d)
         if (!isHttpRedirectResponse()) {
             if (decompressHelper.isCountingBytes())
                 bytesDownloaded += (decompressHelper.uncompressedSize() - uncompressedBefore);
-            setupTransferTimeout();
         }
 
         if (synchronous) {
@@ -1126,7 +1127,6 @@ void QNetworkReplyHttpImplPrivate::replyDownloadData(QByteArray d)
     if (!decompressHelper.isValid() && !isHttpRedirectResponse()) {
         buffer.append(d);
         bytesDownloaded += dataSize;
-        setupTransferTimeout();
     }
     bytesBuffered += dataSize;
 
@@ -1335,6 +1335,8 @@ void QNetworkReplyHttpImplPrivate::replyDownloadMetaData(const QList<QPair<QByte
     Q_Q(QNetworkReplyHttpImpl);
     Q_UNUSED(contentLength);
 
+    resetTransferTimeout();
+
     statusCode = sc;
     reasonPhrase = rp;
 
@@ -1486,7 +1488,6 @@ void QNetworkReplyHttpImplPrivate::replyDownloadProgressSlot(qint64 bytesReceive
         return;
 
     bytesDownloaded = bytesReceived;
-    setupTransferTimeout();
 
     downloadBufferCurrentSize = bytesReceived;
 
@@ -2041,22 +2042,23 @@ void QNetworkReplyHttpImplPrivate::_q_transferTimedOut()
 void QNetworkReplyHttpImplPrivate::setupTransferTimeout()
 {
     Q_Q(QNetworkReplyHttpImpl);
-    if (!transferTimeout) {
-      transferTimeout = new QTimer(q);
-      QObject::connect(transferTimeout, SIGNAL(timeout()),
-                       q, SLOT(_q_transferTimedOut()),
-                       Qt::QueuedConnection);
-    }
-    transferTimeout->stop();
-    if (request.transferTimeoutAsDuration() > 0ms) {
+    if (!transferTimeout && request.transferTimeoutAsDuration() > 0ms) {
+        transferTimeout = new QTimer(q);
+        QObject::connect(transferTimeout, SIGNAL(timeout()), q, SLOT(_q_transferTimedOut()), Qt::QueuedConnection);
         transferTimeout->setSingleShot(true);
-        transferTimeout->setInterval(request.transferTimeoutAsDuration());
-        QMetaObject::invokeMethod(transferTimeout, "start",
-                                  Qt::QueuedConnection);
-
+        transferTimeout->setInterval(request.transferTimeout());
+        transferTimeout->start();
     }
 }
 
+void QNetworkReplyHttpImplPrivate::resetTransferTimeout()
+{
+    if (!transferTimeout || !transferTimeout->isActive())
+        return;
+    transferTimeout->stop();
+    transferTimeout->start();
+}
+
 // need to have this function since the reply is a private member variable
 // and the special backends need to access this.
 void QNetworkReplyHttpImplPrivate::emitReplyUploadProgress(qint64 bytesSent, qint64 bytesTotal)
@@ -2065,8 +2067,6 @@ void QNetworkReplyHttpImplPrivate::emitReplyUploadProgress(qint64 bytesSent, qin
     if (isFinished)
         return;
 
-    setupTransferTimeout();
-
     if (!emitAllUploadProgressSignals) {
         //choke signal emissions, except the first and last signals which are unconditional
         if (uploadProgressSignalChoke.isValid()) {
@@ -2110,8 +2110,10 @@ void QNetworkReplyHttpImplPrivate::_q_finished()
 void QNetworkReplyHttpImplPrivate::finished()
 {
     Q_Q(QNetworkReplyHttpImpl);
-    if (transferTimeout)
-      transferTimeout->stop();
+    if (transferTimeout) {
+        transferTimeout->stop();
+        delete std::exchange(transferTimeout, nullptr); // in case there is a queued start()
+    }
     if (state == Finished || state == Aborted)
         return;
 
diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
index 11897d1420..13cb03c0f4 100644
--- a/src/network/access/qnetworkreplyhttpimpl_p.h
+++ b/src/network/access/qnetworkreplyhttpimpl_p.h
@@ -139,6 +139,7 @@ public:
 
     void _q_transferTimedOut();
     void setupTransferTimeout();
+    void resetTransferTimeout();
 
     void _q_finished();
 
