diff --git a/src/common/downloader.cpp b/src/common/downloader.cpp index 4890dec2..5f408845 100644 --- a/src/common/downloader.cpp +++ b/src/common/downloader.cpp @@ -53,7 +53,7 @@ Authorization::Authorization(const QString &username, const QString &password) { QString concatenated = username + ":" + password; QByteArray data = concatenated.toLocal8Bit().toBase64(); - _header = "Basic " + data; + _header = HTTPHeader("Authorization", "Basic " + data); } NetworkTimeout::NetworkTimeout(int timeout, QNetworkReply *reply) @@ -83,9 +83,10 @@ QNetworkAccessManager *Downloader::_manager = 0; int Downloader::_timeout = 30; bool Downloader::_http2 = true; -bool Downloader::doDownload(const Download &dl, const Authorization &auth) +bool Downloader::doDownload(const Download &dl, const QList &headers) { const QUrl &url = dl.url(); + bool userAgent = false; if (!url.isValid() || !(url.scheme() == QLatin1String("http") || url.scheme() == QLatin1String("https"))) { @@ -103,9 +104,15 @@ bool Downloader::doDownload(const Download &dl, const Authorization &auth) request.setAttribute(ATTR_REDIRECT_POLICY, QNetworkRequest::NoLessSafeRedirectPolicy); request.setAttribute(ATTR_HTTP2_ALLOWED, QVariant(_http2)); - request.setRawHeader("User-Agent", USER_AGENT); - if (!auth.isNull()) - request.setRawHeader("Authorization", auth.header()); + + for (int i = 0; i < headers.size(); i++) { + const HTTPHeader &hdr = headers.at(i); + request.setRawHeader(hdr.key(), hdr.value()); + if (hdr.key() == "User-Agent") + userAgent = true; + } + if (!userAgent) + request.setRawHeader("User-Agent", USER_AGENT); QFile *file = new QFile(tmpName(dl.file())); if (!file->open(QIODevice::WriteOnly)) { @@ -183,12 +190,12 @@ void Downloader::downloadFinished(QNetworkReply *reply) } bool Downloader::get(const QList &list, - const Authorization &authorization) + const QList &headers) { bool finishEmitted = false; for (int i = 0; i < list.count(); i++) - finishEmitted |= doDownload(list.at(i), authorization); + finishEmitted |= doDownload(list.at(i), headers); return finishEmitted; } diff --git a/src/common/downloader.h b/src/common/downloader.h index f9d383e0..9f9d5b91 100644 --- a/src/common/downloader.h +++ b/src/common/downloader.h @@ -7,9 +7,12 @@ #include #include #include +#include "common/kv.h" class QFile; +typedef KV HTTPHeader; + class Download { public: @@ -29,11 +32,11 @@ public: Authorization() {} Authorization(const QString &username, const QString &password); - bool isNull() const {return _header.isNull();} - const QByteArray &header() const {return _header;} + const HTTPHeader &header() const {return _header;} + bool isNull() const {return _header.key().isNull();} private: - QByteArray _header; + HTTPHeader _header; }; class NetworkTimeout : public QObject @@ -60,8 +63,7 @@ class Downloader : public QObject public: Downloader(QObject *parent = 0) : QObject(parent) {} - bool get(const QList &list, const Authorization &authorization - = Authorization()); + bool get(const QList &list, const QList &headers); void clearErrors() {_errorDownloads.clear();} static void setNetworkManager(QNetworkAccessManager *manager) @@ -80,7 +82,7 @@ private: class ReplyTimeout; void insertError(const QUrl &url, QNetworkReply::NetworkError error); - bool doDownload(const Download &dl, const Authorization &auth); + bool doDownload(const Download &dl, const QList &headers); void downloadFinished(QNetworkReply *reply); void readData(QNetworkReply *reply); diff --git a/src/common/kv.h b/src/common/kv.h index 71a42f80..86a4e6c5 100644 --- a/src/common/kv.h +++ b/src/common/kv.h @@ -4,6 +4,7 @@ template class KV { public: + KV() {} KV(const KEY &key, const VALUE &value) : _key(key), _value(value) {} const KEY &key() const {return _key;} diff --git a/src/data/demloader.cpp b/src/data/demloader.cpp index 019ce7a0..02daf665 100644 --- a/src/data/demloader.cpp +++ b/src/data/demloader.cpp @@ -64,7 +64,7 @@ bool DEMLoader::loadTiles(const RectC &rect) } } - return _downloader->get(dl, _authorization); + return _downloader->get(dl, _headers); } bool DEMLoader::checkTiles(const RectC &rect) const @@ -97,3 +97,11 @@ QString DEMLoader::tileFile(const DEM::Tile &tile) const { return _dir.absoluteFilePath(tile.baseName()); } + +void DEMLoader::setAuthorization(const Authorization &authorization) +{ + QList headers; + if (!authorization.isNull()) + headers.append(authorization.header()); + _headers = headers; +} diff --git a/src/data/demloader.h b/src/data/demloader.h index 9961b072..aae5073b 100644 --- a/src/data/demloader.h +++ b/src/data/demloader.h @@ -16,8 +16,7 @@ public: DEMLoader(const QString &dir, QObject *parent = 0); void setUrl(const QString &url) {_url = url;} - void setAuthorization(const Authorization &authorization) - {_authorization = authorization;} + void setAuthorization(const Authorization &authorization); bool loadTiles(const RectC &rect); bool checkTiles(const RectC &rect) const; @@ -34,7 +33,7 @@ private: Downloader *_downloader; QString _url; QDir _dir; - Authorization _authorization; + QList _headers; }; #endif // DEMLOADER_H diff --git a/src/map/mapsource.cpp b/src/map/mapsource.cpp index d5dd8dba..5569611d 100644 --- a/src/map/mapsource.cpp +++ b/src/map/mapsource.cpp @@ -189,14 +189,22 @@ void MapSource::map(QXmlStreamReader &reader, Config &config) else config.dimensions.append(KV (attr.value("id").toString(), reader.readElementText())); + } else if (reader.name() == QLatin1String("header")) { + QXmlStreamAttributes attr = reader.attributes(); + if (!attr.hasAttribute("name")) + reader.raiseError("Missing header name"); + else + config.headers.append(HTTPHeader( + attr.value("name").toString().toLatin1(), + reader.readElementText().toLatin1())); } else if (reader.name() == QLatin1String("crs")) { config.coordinateSystem = coordinateSystem(reader); config.crs = reader.readElementText(); } else if (reader.name() == QLatin1String("authorization")) { QXmlStreamAttributes attr = reader.attributes(); - config.authorization = Authorization( - attr.value("username").toString(), + Authorization auth(attr.value("username").toString(), attr.value("password").toString()); + config.headers.append(auth.header()); reader.skipCurrentElement(); } else if (reader.name() == QLatin1String("tile")) { tile(reader, config); @@ -252,24 +260,24 @@ Map *MapSource::create(const QString &path, bool *isDir) case WMTS: return new WMTSMap(path, config.name, WMTS::Setup(config.url, config.layer, config.set, config.style, config.format, config.rest, - config.coordinateSystem, config.dimensions, config.authorization), + config.coordinateSystem, config.dimensions, config.headers), config.tileRatio); case WMS: return new WMSMap(path, config.name, WMS::Setup(config.url, config.layer, config.style, config.format, config.crs, - config.coordinateSystem, config.dimensions, config.authorization), + config.coordinateSystem, config.dimensions, config.headers), config.tileSize); case TMS: return new OnlineMap(path, config.name, config.url, config.zooms, - config.bounds, config.tileRatio, config.authorization, + config.bounds, config.tileRatio, config.headers, config.tileSize, config.scalable, true, false); case OSM: return new OnlineMap(path, config.name, config.url, config.zooms, - config.bounds, config.tileRatio, config.authorization, + config.bounds, config.tileRatio, config.headers, config.tileSize, config.scalable, false, false); case QuadTiles: return new OnlineMap(path, config.name, config.url, config.zooms, - config.bounds, config.tileRatio, config.authorization, + config.bounds, config.tileRatio, config.headers, config.tileSize, config.scalable, false, true); default: return new InvalidMap(path, "Invalid map type"); diff --git a/src/map/mapsource.h b/src/map/mapsource.h index 1be457ee..97542a28 100644 --- a/src/map/mapsource.h +++ b/src/map/mapsource.h @@ -40,7 +40,7 @@ private: CoordinateSystem coordinateSystem; bool rest; QList > dimensions; - Authorization authorization; + QList headers; qreal tileRatio; int tileSize; bool scalable; diff --git a/src/map/onlinemap.cpp b/src/map/onlinemap.cpp index 2746a414..e9841670 100644 --- a/src/map/onlinemap.cpp +++ b/src/map/onlinemap.cpp @@ -10,7 +10,7 @@ OnlineMap::OnlineMap(const QString &fileName, const QString &name, const QString &url, const Range &zooms, const RectC &bounds, qreal tileRatio, - const Authorization &authorization, int tileSize, bool scalable, bool invertY, + const QList &headers, int tileSize, bool scalable, bool invertY, bool quadTiles, QObject *parent) : Map(fileName, parent), _name(name), _zooms(zooms), _bounds(bounds), _zoom(_zooms.max()), _tileSize(tileSize), _mapRatio(1.0), @@ -19,7 +19,7 @@ OnlineMap::OnlineMap(const QString &fileName, const QString &name, _tileLoader = new TileLoader(QDir(ProgramPaths::tilesDir()).filePath(_name), this); _tileLoader->setUrl(url); - _tileLoader->setAuthorization(authorization); + _tileLoader->setHeaders(headers); _tileLoader->setQuadTiles(quadTiles); connect(_tileLoader, &TileLoader::finished, this, &OnlineMap::tilesLoaded); } diff --git a/src/map/onlinemap.h b/src/map/onlinemap.h index 6ac36fd0..9a45e781 100644 --- a/src/map/onlinemap.h +++ b/src/map/onlinemap.h @@ -13,7 +13,7 @@ class OnlineMap : public Map public: OnlineMap(const QString &fileName, const QString &name, const QString &url, const Range &zooms, const RectC &bounds, qreal tileRatio, - const Authorization &authorization, int tileSize, bool scalable, + const QList &headers, int tileSize, bool scalable, bool invertY, bool quadTiles, QObject *parent = 0); QString name() const {return _name;} diff --git a/src/map/tileloader.cpp b/src/map/tileloader.cpp index ee91c69a..168d5943 100644 --- a/src/map/tileloader.cpp +++ b/src/map/tileloader.cpp @@ -88,7 +88,7 @@ void TileLoader::loadTilesAsync(QVector &list) } if (!dl.empty()) - _downloader->get(dl, _authorization); + _downloader->get(dl, _headers); QFuture future = QtConcurrent::map(imgs, &TileImage::load); future.waitForFinished(); @@ -130,7 +130,7 @@ void TileLoader::loadTilesSync(QVector &list) if (!dl.empty()) { QEventLoop wait; connect(_downloader, &Downloader::finished, &wait, &QEventLoop::quit); - if (_downloader->get(dl, _authorization)) + if (_downloader->get(dl, _headers)) wait.exec(); for (int i = 0; i < tl.size(); i++) { diff --git a/src/map/tileloader.h b/src/map/tileloader.h index 9daf9c57..86286b12 100644 --- a/src/map/tileloader.h +++ b/src/map/tileloader.h @@ -14,8 +14,7 @@ public: TileLoader(const QString &dir, QObject *parent = 0); void setUrl(const QString &url) {_url = url;} - void setAuthorization(const Authorization &authorization) - {_authorization = authorization;} + void setHeaders(const QList &headers) {_headers = headers;} void setScaledSize(int size); void setQuadTiles(bool quadTiles) {_quadTiles = quadTiles;} @@ -33,7 +32,7 @@ private: Downloader *_downloader; QString _url; QString _dir; - Authorization _authorization; + QList _headers; int _scaledSize; bool _quadTiles; }; diff --git a/src/map/wms.cpp b/src/map/wms.cpp index 1860015b..ba336abc 100644 --- a/src/map/wms.cpp +++ b/src/map/wms.cpp @@ -345,7 +345,7 @@ WMS::WMS(const QString &file, const WMS::Setup &setup, QObject *parent) QList dl; dl.append(Download(url, _path)); - _valid = downloader->get(dl, _setup.authorization()); + _valid = downloader->get(dl, _setup.headers()); } else { _ready = true; _valid = parseCapabilities(); diff --git a/src/map/wms.h b/src/map/wms.h index 6bfc6828..3734909d 100644 --- a/src/map/wms.h +++ b/src/map/wms.h @@ -23,13 +23,13 @@ public: Setup(const QString &url, const QString &layer, const QString &style, const QString &format, const QString &crs, const CoordinateSystem &cs, const QList > &dimensions, - const Authorization &authorization = Authorization()) + const QList &headers) : _url(url), _layer(layer), _style(style), _format(format), _crs(crs), _cs(cs), _dimensions(dimensions), - _authorization(authorization) {} + _headers(headers) {} const QString &url() const {return _url;} - const Authorization &authorization() const {return _authorization;} + const QList &headers() const {return _headers;} const QString &layer() const {return _layer;} const QString &style() const {return _style;} const QString &format() const {return _format;} @@ -46,7 +46,7 @@ public: QString _crs; CoordinateSystem _cs; QList > _dimensions; - Authorization _authorization; + QList _headers; }; diff --git a/src/map/wmsmap.cpp b/src/map/wmsmap.cpp index 8147a73e..b8b6bce7 100644 --- a/src/map/wmsmap.cpp +++ b/src/map/wmsmap.cpp @@ -74,7 +74,7 @@ WMSMap::WMSMap(const QString &fileName, const QString &name, QString tilesDir(QDir(ProgramPaths::tilesDir()).filePath(_name)); _tileLoader = new TileLoader(tilesDir, this); - _tileLoader->setAuthorization(setup.authorization()); + _tileLoader->setHeaders(setup.headers()); connect(_tileLoader, &TileLoader::finished, this, &WMSMap::tilesLoaded); _wms = new WMS(QDir(tilesDir).filePath(CAPABILITIES_FILE), setup, this); diff --git a/src/map/wmts.cpp b/src/map/wmts.cpp index 205f48c3..14f112bd 100644 --- a/src/map/wmts.cpp +++ b/src/map/wmts.cpp @@ -361,7 +361,7 @@ WMTS::WMTS(const QString &file, const WMTS::Setup &setup, QObject *parent) QList dl; dl.append(Download(url.toString(), _path)); - _valid = downloader->get(dl, _setup.authorization()); + _valid = downloader->get(dl, _setup.headers()); } else { _ready = true; _valid = init(); diff --git a/src/map/wmts.h b/src/map/wmts.h index d0b88d6b..85597a5d 100644 --- a/src/map/wmts.h +++ b/src/map/wmts.h @@ -27,13 +27,13 @@ public: const QString &style, const QString &format, bool rest, const CoordinateSystem &cs, const QList > &dimensions, - const Authorization &authorization = Authorization()) + const QList &headers) : _url(url), _layer(layer), _set(set), _style(style), _format(format), _rest(rest), _cs(cs), _dimensions(dimensions), - _authorization(authorization) {} + _headers(headers) {} const QString &url() const {return _url;} - const Authorization &authorization() const {return _authorization;} + const QList &headers() const {return _headers;} const QString &layer() const {return _layer;} const QString &set() const {return _set;} const QString &style() const {return _style;} @@ -52,7 +52,7 @@ public: bool _rest; CoordinateSystem _cs; QList > _dimensions; - Authorization _authorization; + QList _headers; }; class Zoom diff --git a/src/map/wmtsmap.cpp b/src/map/wmtsmap.cpp index 1da2dd29..f01c82d8 100644 --- a/src/map/wmtsmap.cpp +++ b/src/map/wmtsmap.cpp @@ -20,7 +20,7 @@ WMTSMap::WMTSMap(const QString &fileName, const QString &name, QString tilesDir(QDir(ProgramPaths::tilesDir()).filePath(_name)); _tileLoader = new TileLoader(tilesDir, this); - _tileLoader->setAuthorization(setup.authorization()); + _tileLoader->setHeaders(setup.headers()); connect(_tileLoader, &TileLoader::finished, this, &WMTSMap::tilesLoaded); _wmts = new WMTS(QDir(tilesDir).filePath(CAPABILITIES_FILE), setup, this);