1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-01-31 09:05:14 +01:00

Properly handle connection timeouts

(count timeout from last received data chunk, not for the whole download)
This commit is contained in:
Martin Tůma 2021-08-29 20:28:08 +02:00
parent 018d0ba085
commit 94a0158243
2 changed files with 42 additions and 28 deletions

View File

@ -1,7 +1,6 @@
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QBasicTimer>
#include <QDir> #include <QDir>
#include <QTimerEvent> #include <QTimerEvent>
#include "common/config.h" #include "common/config.h"
@ -51,33 +50,28 @@ Authorization::Authorization(const QString &username, const QString &password)
_header = "Basic " + data; _header = "Basic " + data;
} }
class Downloader::ReplyTimeout : public QObject NetworkTimeout::NetworkTimeout(int timeout, QNetworkReply *reply)
: QObject(reply), _timeout(timeout)
{ {
public: connect(reply, &QIODevice::readyRead, this, &NetworkTimeout::reset);
static void setTimeout(QNetworkReply *reply, int timeout) _timer.start(timeout * 1000, this);
{ }
Q_ASSERT(reply);
new ReplyTimeout(reply, timeout);
}
private: void NetworkTimeout::reset()
ReplyTimeout(QNetworkReply *reply, int timeout) : QObject(reply) {
{ _timer.start(_timeout * 1000, this);
_timer.start(timeout * 1000, this); }
}
void timerEvent(QTimerEvent *ev) void NetworkTimeout::timerEvent(QTimerEvent *ev)
{ {
if (!_timer.isActive() || ev->timerId() != _timer.timerId()) if (!_timer.isActive() || ev->timerId() != _timer.timerId())
return; return;
QNetworkReply *reply = static_cast<QNetworkReply*>(parent()); QNetworkReply *reply = static_cast<QNetworkReply*>(parent());
if (reply->isRunning()) if (reply->isRunning())
reply->close(); reply->close();
_timer.stop(); _timer.stop();
} }
QBasicTimer _timer;
};
QNetworkAccessManager *Downloader::_manager = 0; QNetworkAccessManager *Downloader::_manager = 0;
int Downloader::_timeout = 30; int Downloader::_timeout = 30;
@ -108,7 +102,7 @@ bool Downloader::doDownload(const Download &dl, const QByteArray &authorization)
request.setRawHeader("Authorization", authorization); request.setRawHeader("Authorization", authorization);
QFile *file = new QFile(tmpName(dl.file())); QFile *file = new QFile(tmpName(dl.file()));
if (!file->open(QIODevice::ReadWrite)) { if (!file->open(QIODevice::WriteOnly)) {
qWarning("%s: %s", qPrintable(file->fileName()), qWarning("%s: %s", qPrintable(file->fileName()),
qPrintable(file->errorString())); qPrintable(file->errorString()));
_errorDownloads.insert(url, RETRIES); _errorDownloads.insert(url, RETRIES);
@ -121,7 +115,9 @@ bool Downloader::doDownload(const Download &dl, const QByteArray &authorization)
_currentDownloads.insert(url, file); _currentDownloads.insert(url, file);
if (reply->isRunning()) { if (reply->isRunning()) {
ReplyTimeout::setTimeout(reply, _timeout); /* Starting with Qt 5.15 this can be replaced by
QNetworkRequest::setTransferTimeout() */
new NetworkTimeout(_timeout, reply);
connect(reply, &QIODevice::readyRead, this, &Downloader::emitReadReady); connect(reply, &QIODevice::readyRead, this, &Downloader::emitReadReady);
connect(reply, &QNetworkReply::finished, this, &Downloader::emitFinished); connect(reply, &QNetworkReply::finished, this, &Downloader::emitFinished);
} else { } else {
@ -134,12 +130,12 @@ bool Downloader::doDownload(const Download &dl, const QByteArray &authorization)
void Downloader::emitFinished() void Downloader::emitFinished()
{ {
downloadFinished(qobject_cast<QNetworkReply*>(sender())); downloadFinished(static_cast<QNetworkReply*>(sender()));
} }
void Downloader::emitReadReady() void Downloader::emitReadReady()
{ {
readData(qobject_cast<QNetworkReply*>(sender())); readData(static_cast<QNetworkReply*>(sender()));
} }
void Downloader::insertError(const QUrl &url, QNetworkReply::NetworkError error) void Downloader::insertError(const QUrl &url, QNetworkReply::NetworkError error)

View File

@ -3,6 +3,7 @@
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include <QNetworkReply> #include <QNetworkReply>
#include <QBasicTimer>
#include <QUrl> #include <QUrl>
#include <QList> #include <QList>
#include <QHash> #include <QHash>
@ -34,6 +35,23 @@ private:
QByteArray _header; QByteArray _header;
}; };
class NetworkTimeout : public QObject
{
Q_OBJECT
public:
NetworkTimeout(int timeout, QNetworkReply *reply);
private slots:
void reset();
private:
void timerEvent(QTimerEvent *ev);
QBasicTimer _timer;
int _timeout;
};
class Downloader : public QObject class Downloader : public QObject
{ {
Q_OBJECT Q_OBJECT