1#include "http_file_source.hpp"
2#include "http_request.hpp"
3
4#include <mbgl/util/logging.hpp>
5
6#include <QByteArray>
7#include <QDir>
8#include <QNetworkProxyFactory>
9#include <QNetworkReply>
10#include <QSslConfiguration>
11
12namespace mbgl {
13
14HTTPFileSource::Impl::Impl() : m_manager(new QNetworkAccessManager(this))
15{
16 QNetworkProxyFactory::setUseSystemConfiguration(true);
17}
18
19void HTTPFileSource::Impl::request(HTTPRequest* req)
20{
21 QUrl url = req->requestUrl();
22
23 QPair<QNetworkReply*, QVector<HTTPRequest*>>& data = m_pending[url];
24 QVector<HTTPRequest*>& requestsVector = data.second;
25 requestsVector.append(t: req);
26
27 if (requestsVector.size() > 1) {
28 return;
29 }
30
31 QNetworkRequest networkRequest = req->networkRequest();
32#if QT_VERSION < 0x060000
33# if QT_VERSION >= 0x050900
34 networkRequest.setAttribute(code: QNetworkRequest::RedirectPolicyAttribute,
35 value: QNetworkRequest::NoLessSafeRedirectPolicy);
36# elif QT_VERSION >= 0x050600
37 networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
38# endif
39#endif
40
41 data.first = m_manager->get(request: networkRequest);
42 connect(sender: data.first, SIGNAL(finished()), receiver: this, SLOT(onReplyFinished()));
43 connect(sender: data.first, SIGNAL(error(QNetworkReply::NetworkError)), receiver: this, SLOT(onReplyFinished()));
44}
45
46void HTTPFileSource::Impl::cancel(HTTPRequest* req)
47{
48 QUrl url = req->requestUrl();
49
50 auto it = m_pending.find(akey: url);
51 if (it == m_pending.end()) {
52 return;
53 }
54
55 QPair<QNetworkReply*, QVector<HTTPRequest*>>& data = it.value();
56 QNetworkReply* reply = data.first;
57 QVector<HTTPRequest*>& requestsVector = data.second;
58
59 for (int i = 0; i < requestsVector.size(); ++i) {
60 if (req == requestsVector.at(i)) {
61 requestsVector.remove(i);
62 break;
63 }
64 }
65
66 if (requestsVector.empty()) {
67 m_pending.erase(it);
68#if QT_VERSION >= 0x050000
69 reply->abort();
70#else
71 // XXX: We should be aborting the reply here
72 // but a bug on Qt4 causes the connection of
73 // other ongoing requests to drop if we call
74 // abort() too often (and we do).
75 Q_UNUSED(reply);
76#endif
77 }
78}
79
80void HTTPFileSource::Impl::onReplyFinished()
81{
82 QNetworkReply* reply = qobject_cast<QNetworkReply *>(object: sender());
83 const QUrl& url = reply->request().url();
84
85 auto it = m_pending.find(akey: url);
86 if (it == m_pending.end()) {
87 reply->deleteLater();
88 return;
89 }
90
91 QByteArray data = reply->readAll();
92 QVector<HTTPRequest*>& requestsVector = it.value().second;
93 for (auto req : requestsVector) {
94 req->handleNetworkReply(reply, data);
95 }
96
97 m_pending.erase(it);
98 reply->deleteLater();
99}
100
101HTTPFileSource::HTTPFileSource()
102 : impl(std::make_unique<Impl>()) {
103}
104
105HTTPFileSource::~HTTPFileSource() = default;
106
107std::unique_ptr<AsyncRequest> HTTPFileSource::request(const Resource& resource, Callback callback)
108{
109 return std::make_unique<HTTPRequest>(args: impl.get(), args: resource, args&: callback);
110}
111
112uint32_t HTTPFileSource::maximumConcurrentRequests() {
113#if QT_VERSION >= 0x050000
114 return 20;
115#else
116 return 10;
117#endif
118}
119
120} // namespace mbgl
121

source code of qtlocation/src/3rdparty/mapbox-gl-native/platform/qt/src/http_file_source.cpp