@@ -110,6 +110,40 @@ void AbstractNetworkJob::setupConnections(QNetworkReply *reply)
110110 connect (reply, &QNetworkReply::downloadProgress, this , &AbstractNetworkJob::networkActivity);
111111 connect (reply, &QNetworkReply::uploadProgress, this , &AbstractNetworkJob::networkActivity);
112112 connect (reply, &QNetworkReply::redirected, this , [reply, this ] (const QUrl &url) { emit redirected (reply, url, 0 );});
113+
114+ if (_stallDetectionEnabled) {
115+ // Reset per-reply state so progress from a previous attempt does not
116+ // carry over (e.g. after an HTTP redirect).
117+ _lastTransferBytes = -1 ;
118+ connect (reply, &QNetworkReply::uploadProgress, this , [this ](qint64 bytesSent, qint64) {
119+ if (bytesSent > _lastTransferBytes) {
120+ _lastTransferBytes = bytesSent;
121+ _stallTimer.start ();
122+ }
123+ });
124+ connect (reply, &QNetworkReply::downloadProgress, this , [this ](qint64 bytesReceived, qint64) {
125+ if (bytesReceived > _lastTransferBytes) {
126+ _lastTransferBytes = bytesReceived;
127+ _stallTimer.start ();
128+ }
129+ });
130+ _stallTimer.start ();
131+ }
132+ }
133+
134+ void AbstractNetworkJob::enableStallDetection (int timeoutMs)
135+ {
136+ _stallDetectionEnabled = true ;
137+ _stallTimer.setSingleShot (true );
138+ _stallTimer.setInterval (timeoutMs);
139+ connect (&_stallTimer, &QTimer::timeout, this , [this ]() {
140+ qCWarning (lcNetworkJob) << " Transfer stalled: no bytes transferred for"
141+ << _stallTimer.interval () / 1000 << " seconds on" << path ();
142+ emit transferStalled ();
143+ if (reply ()) {
144+ reply ()->abort ();
145+ }
146+ });
113147}
114148
115149QNetworkReply *AbstractNetworkJob::addTimer (QNetworkReply *reply)
@@ -175,6 +209,7 @@ QUrl AbstractNetworkJob::makeDavUrl(const QString &relativePath) const
175209void AbstractNetworkJob::slotFinished ()
176210{
177211 _timer.stop ();
212+ _stallTimer.stop ();
178213
179214 if (_reply->error () == QNetworkReply::SslHandshakeFailedError) {
180215 qCWarning (lcNetworkJob) << " SslHandshakeFailedError: " << errorString () << " : can be caused by a webserver wanting SSL client certificates" ;
0 commit comments