1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-28 05:34:47 +01:00

Fixed download error handling in case of redirects

Do not download tiles multiple times.
This commit is contained in:
Martin Tůma 2017-01-16 09:53:01 +01:00
parent a458b82e37
commit 5581cff55b
2 changed files with 30 additions and 13 deletions

View File

@ -17,25 +17,32 @@
#define USER_AGENT \ #define USER_AGENT \
APP_NAME "/" APP_VERSION " (" PLATFORM_STR "; Qt " QT_VERSION_STR ")" 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() Downloader::Downloader()
{ {
connect(&_manager, SIGNAL(finished(QNetworkReply*)), connect(&_manager, SIGNAL(finished(QNetworkReply*)),
SLOT(downloadFinished(QNetworkReply*))); SLOT(downloadFinished(QNetworkReply*)));
} }
bool Downloader::doDownload(const Download &dl) bool Downloader::doDownload(const Download &dl, const QUrl &origin)
{ {
QUrl url(dl.url()); QUrl url(dl.url());
if (_errorDownloads.contains(url)) if (_errorDownloads.contains(url))
return false; return false;
if (_currentDownloads.contains(url))
return false;
QNetworkRequest request(url); 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); request.setRawHeader("User-Agent", USER_AGENT);
QNetworkReply *reply = _manager.get(request); QNetworkReply *reply = _manager.get(request);
_currentDownloads.append(reply); _currentDownloads.insert(url, reply);
return true; return true;
} }
@ -58,26 +65,36 @@ bool Downloader::saveToDisk(const QString &filename, QIODevice *data)
void Downloader::downloadFinished(QNetworkReply *reply) void Downloader::downloadFinished(QNetworkReply *reply)
{ {
QUrl url = reply->url(); QUrl url = reply->request().url();
if (reply->error()) { if (reply->error()) {
_errorDownloads.insert(url); QUrl origin = reply->request().attribute(ATTR_ORIGIN).toUrl();
fprintf(stderr, "Error downloading map tile: %s: %s\n", if (origin.isEmpty()) {
url.toEncoded().constData(), qPrintable(reply->errorString())); _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 { } else {
QUrl redirect = reply->attribute( QUrl redirect = reply->attribute(
QNetworkRequest::RedirectionTargetAttribute).toUrl(); QNetworkRequest::RedirectionTargetAttribute).toUrl();
QString filename = reply->request().attribute(QNetworkRequest::User) QString filename = reply->request().attribute(ATTR_FILE)
.toString(); .toString();
if (!redirect.isEmpty()) { if (!redirect.isEmpty()) {
QUrl origin = reply->request().attribute(ATTR_ORIGIN).toUrl();
Download dl(redirect, filename); Download dl(redirect, filename);
doDownload(dl); doDownload(dl, origin.isEmpty() ? url : origin);
} else } else
if (!saveToDisk(filename, reply)) if (!saveToDisk(filename, reply))
_errorDownloads.insert(url); _errorDownloads.insert(url);
} }
_currentDownloads.removeAll(reply); _currentDownloads.remove(url);
reply->deleteLater(); reply->deleteLater();
if (_currentDownloads.isEmpty()) if (_currentDownloads.isEmpty())

View File

@ -5,7 +5,7 @@
#include <QNetworkRequest> #include <QNetworkRequest>
#include <QNetworkReply> #include <QNetworkReply>
#include <QUrl> #include <QUrl>
#include <QList> #include <QMap>
#include <QSet> #include <QSet>
@ -43,11 +43,11 @@ private:
Downloader(Downloader const&); Downloader(Downloader const&);
void operator=(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); bool saveToDisk(const QString &filename, QIODevice *data);
QNetworkAccessManager _manager; QNetworkAccessManager _manager;
QList<QNetworkReply *> _currentDownloads; QMap<QUrl, QNetworkReply *> _currentDownloads;
QSet<QUrl> _errorDownloads; QSet<QUrl> _errorDownloads;
}; };