diff --git a/src/map/downloader.cpp b/src/map/downloader.cpp index 23538baa..45e81c7f 100644 --- a/src/map/downloader.cpp +++ b/src/map/downloader.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include "config.h" #include "downloader.h" @@ -26,6 +25,7 @@ #define ATTR_LEVEL (QNetworkRequest::Attribute)(QNetworkRequest::User + 2) #define MAX_REDIRECT_LEVEL 5 +#define RETRIES 3 Authorization::Authorization(const QString &username, const QString &password) @@ -89,10 +89,12 @@ bool Downloader::doDownload(const Download &dl, if (!url.isValid() || !(url.scheme() == "http" || url.scheme() == "https")) { qWarning("%s: Invalid URL\n", qPrintable(url.toString())); + if (redirect) + _errorDownloads.insert(redirect->origin(), RETRIES); return false; } - if (_errorDownloads.contains(url)) + if (_errorDownloads.value(url) >= RETRIES) return false; if (_currentDownloads.contains(url) && !redirect) return false; @@ -141,18 +143,27 @@ bool Downloader::saveToDisk(const QString &filename, QIODevice *data) return true; } +void Downloader::insertError(const QUrl &url, QNetworkReply::NetworkError error) +{ + if (error == QNetworkReply::OperationCanceledError) + _errorDownloads.insert(url, _errorDownloads.value(url) + 1); + else + _errorDownloads.insert(url, RETRIES); +} + void Downloader::downloadFinished(QNetworkReply *reply) { QUrl url = reply->request().url(); + QNetworkReply::NetworkError error = reply->error(); - if (reply->error()) { + if (error) { QUrl origin = reply->request().attribute(ATTR_ORIGIN).toUrl(); if (origin.isEmpty()) { - _errorDownloads.insert(url); + insertError(url, error); qWarning("Error downloading file: %s: %s\n", url.toEncoded().constData(), qPrintable(reply->errorString())); } else { - _errorDownloads.insert(origin); + insertError(origin, error); qWarning("Error downloading file: %s -> %s: %s\n", origin.toEncoded().constData(), url.toEncoded().constData(), qPrintable(reply->errorString())); @@ -167,7 +178,7 @@ void Downloader::downloadFinished(QNetworkReply *reply) int level = reply->request().attribute(ATTR_LEVEL).toInt(); if (level >= MAX_REDIRECT_LEVEL) { - _errorDownloads.insert(origin); + _errorDownloads.insert(origin, RETRIES); qWarning("Error downloading file: %s: " "redirect level limit reached (redirect loop?)\n", origin.toEncoded().constData()); @@ -182,13 +193,12 @@ void Downloader::downloadFinished(QNetworkReply *reply) Redirect redirect(origin.isEmpty() ? url : origin, level + 1); Download dl(redirectUrl, filename); - if (!doDownload(dl, reply->request().rawHeader("Authorization"), - &redirect)) - _errorDownloads.insert(origin.isEmpty() ? url : origin); + doDownload(dl, reply->request().rawHeader("Authorization"), + &redirect); } } else { if (!saveToDisk(filename, reply)) - _errorDownloads.insert(url); + _errorDownloads.insert(url, RETRIES); } } diff --git a/src/map/downloader.h b/src/map/downloader.h index a6b1048e..6dea1d42 100644 --- a/src/map/downloader.h +++ b/src/map/downloader.h @@ -2,11 +2,12 @@ #define DOWNLOADER_H #include +#include #include #include #include +#include -class QNetworkReply; class Download { @@ -59,12 +60,13 @@ private: class Redirect; class ReplyTimeout; + void insertError(const QUrl &url, QNetworkReply::NetworkError error); bool doDownload(const Download &dl, const QByteArray &authorization, const Redirect *redirect = 0); bool saveToDisk(const QString &filename, QIODevice *data); QSet _currentDownloads; - QSet _errorDownloads; + QHash _errorDownloads; static int _timeout; static QNetworkAccessManager *_manager;