From 5581cff55b3cebe28458be379bab684ce35ec828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20T=C5=AFma?= Date: Mon, 16 Jan 2017 09:53:01 +0100 Subject: [PATCH] Fixed download error handling in case of redirects Do not download tiles multiple times. --- src/downloader.cpp | 37 +++++++++++++++++++++++++++---------- src/downloader.h | 6 +++--- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/downloader.cpp b/src/downloader.cpp index 2c42d3de..d70ef51b 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -17,25 +17,32 @@ #define USER_AGENT \ APP_NAME "/" APP_VERSION " (" PLATFORM_STR "; Qt " QT_VERSION_STR ")" +#define ATTR_FILE QNetworkRequest::User +#define ATTR_ORIGIN (QNetworkRequest::Attribute)(QNetworkRequest::User + 1) + Downloader::Downloader() { connect(&_manager, SIGNAL(finished(QNetworkReply*)), SLOT(downloadFinished(QNetworkReply*))); } -bool Downloader::doDownload(const Download &dl) +bool Downloader::doDownload(const Download &dl, const QUrl &origin) { QUrl url(dl.url()); if (_errorDownloads.contains(url)) return false; + if (_currentDownloads.contains(url)) + return false; QNetworkRequest request(url); - request.setAttribute(QNetworkRequest::User, QVariant(dl.file())); + request.setAttribute(ATTR_FILE, QVariant(dl.file())); + if (!origin.isEmpty()) + request.setAttribute(ATTR_ORIGIN, QVariant(origin)); request.setRawHeader("User-Agent", USER_AGENT); QNetworkReply *reply = _manager.get(request); - _currentDownloads.append(reply); + _currentDownloads.insert(url, reply); return true; } @@ -58,26 +65,36 @@ bool Downloader::saveToDisk(const QString &filename, QIODevice *data) void Downloader::downloadFinished(QNetworkReply *reply) { - QUrl url = reply->url(); + QUrl url = reply->request().url(); + if (reply->error()) { - _errorDownloads.insert(url); - fprintf(stderr, "Error downloading map tile: %s: %s\n", - url.toEncoded().constData(), qPrintable(reply->errorString())); + QUrl origin = reply->request().attribute(ATTR_ORIGIN).toUrl(); + if (origin.isEmpty()) { + _errorDownloads.insert(url); + fprintf(stderr, "Error downloading map tile: %s: %s\n", + url.toEncoded().constData(), qPrintable(reply->errorString())); + } else { + _errorDownloads.insert(origin); + fprintf(stderr, "Error downloading map tile: %s -> %s: %s\n", + origin.toEncoded().constData(), url.toEncoded().constData(), + qPrintable(reply->errorString())); + } } else { QUrl redirect = reply->attribute( QNetworkRequest::RedirectionTargetAttribute).toUrl(); - QString filename = reply->request().attribute(QNetworkRequest::User) + QString filename = reply->request().attribute(ATTR_FILE) .toString(); if (!redirect.isEmpty()) { + QUrl origin = reply->request().attribute(ATTR_ORIGIN).toUrl(); Download dl(redirect, filename); - doDownload(dl); + doDownload(dl, origin.isEmpty() ? url : origin); } else if (!saveToDisk(filename, reply)) _errorDownloads.insert(url); } - _currentDownloads.removeAll(reply); + _currentDownloads.remove(url); reply->deleteLater(); if (_currentDownloads.isEmpty()) diff --git a/src/downloader.h b/src/downloader.h index ee16262c..90badba3 100644 --- a/src/downloader.h +++ b/src/downloader.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include @@ -43,11 +43,11 @@ private: Downloader(Downloader const&); void operator=(Downloader const&); - bool doDownload(const Download &dl); + bool doDownload(const Download &dl, const QUrl &origin = QUrl()); bool saveToDisk(const QString &filename, QIODevice *data); QNetworkAccessManager _manager; - QList _currentDownloads; + QMap _currentDownloads; QSet _errorDownloads; };