Line data Source code
1 : #include "SimpleHTTPDownloader.h"
2 :
3 104 : SimpleHTTPDownloader::SimpleHTTPDownloader(int timeoutMS, QObject *parent, QNetworkAccessManager* networkManager) :
4 : FangObject(parent),
5 104 : manager(networkManager ? networkManager : new FangNetworkAccessManager(this)),
6 104 : ownsManager(networkManager == nullptr),
7 104 : timeoutMS(timeoutMS),
8 104 : currentReply(nullptr),
9 208 : redirectAttempts(0)
10 : {
11 104 : timeout.setSingleShot(true);
12 :
13 : // Signals!
14 104 : connect(manager, &QNetworkAccessManager::finished, this, &SimpleHTTPDownloader::onRequestFinished);
15 104 : connect(&timeout, &QTimer::timeout, this, &SimpleHTTPDownloader::onTimeout);
16 104 : }
17 :
18 104 : SimpleHTTPDownloader::~SimpleHTTPDownloader()
19 : {
20 104 : if (currentReply) {
21 6 : currentReply->deleteLater();
22 6 : currentReply = nullptr;
23 : }
24 104 : }
25 :
26 7 : void SimpleHTTPDownloader::load(const QUrl &url)
27 : {
28 : // Reset our counter.
29 7 : redirectAttempts = 0;
30 :
31 7 : loadInternal(url);
32 7 : }
33 :
34 7 : void SimpleHTTPDownloader::loadInternal(const QUrl &url)
35 : {
36 : // Delete last reply if needed.
37 7 : if (currentReply) {
38 0 : currentReply->deleteLater();
39 0 : currentReply = nullptr;
40 : }
41 :
42 7 : if (url.isRelative()) {
43 1 : emit error("Relative URLs are not allowed");
44 : } else {
45 6 : QNetworkRequest request(url);
46 6 : currentReply = manager->get(request);
47 6 : connect(currentReply, &QNetworkReply::downloadProgress, this,
48 6 : &SimpleHTTPDownloader::onDownloadProgress);
49 :
50 : // Reset timer
51 6 : timeout.setInterval(timeoutMS);
52 6 : }
53 7 : }
54 :
55 30 : void SimpleHTTPDownloader::onRequestFinished(QNetworkReply *reply)
56 : {
57 : // Only process replies that belong to us
58 30 : if (reply != currentReply) {
59 25 : return;
60 : }
61 :
62 : // Check for errors.
63 6 : if (reply->error() != QNetworkReply::NoError) {
64 1 : QString netError = "SimpleHTTPDownloader error: " + reply->errorString();
65 1 : qDebug() << netError;
66 1 : emit error(netError);
67 :
68 1 : return;
69 1 : }
70 :
71 : // Handle HTTP redirects.
72 5 : QVariant redirectVariant = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
73 5 : if (!redirectVariant.isNull()) {
74 0 : if (redirectAttempts > MAX_REDIRECTS) {
75 0 : emit error("Maximum HTTP redirects");
76 :
77 0 : return;
78 : }
79 :
80 : // Bump counter and call our internal load method that doesn't reset it.
81 0 : redirectAttempts++;
82 :
83 0 : QUrl redirectURL = redirectVariant.toUrl();
84 0 : loadInternal(redirectURL);
85 :
86 0 : return;
87 0 : }
88 :
89 : // We're done!
90 5 : emit finished(reply->readAll());
91 5 : }
92 :
93 0 : void SimpleHTTPDownloader::onDownloadProgress(qint64 bytesReceived, qint64 bytesTotal)
94 : {
95 : Q_UNUSED(bytesReceived);
96 : Q_UNUSED(bytesTotal);
97 :
98 : // Reset timer
99 0 : timeout.setInterval(timeoutMS);
100 0 : }
101 :
102 0 : void SimpleHTTPDownloader::onTimeout()
103 : {
104 0 : if (currentReply) {
105 0 : currentReply->abort();
106 0 : currentReply->deleteLater();
107 0 : currentReply = nullptr;
108 :
109 0 : emit error("SimpleHTTPDownloader timeout!");
110 : }
111 0 : }
112 :
|