-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathdownloader.cpp
111 lines (94 loc) · 2.94 KB
/
downloader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <QFileDialog>
#include <QMessageBox>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QDebug>
#include <QTemporaryFile>
#include "downloader.h"
namespace Yate {
Downloader::Downloader(QObject *parent)
: QObject{parent}, manager_(new QNetworkAccessManager)
{
isDownloading_.storeRelaxed(0);
expectedHash_ = "";
connect(manager_, &QNetworkAccessManager::finished, this, &Downloader::onManagerFinished);
}
void Downloader::onManagerFinished(QNetworkReply *reply)
{
qDebug() << "Download finished.";
isDownloading_.storeRelaxed(0);
if (reply->error()) {
qCritical() << "Download failed with network error " << reply->errorString();
emit onDownloadFailed("Update download failed: " + reply->errorString());
} else {
bool ok;
QString filename = saveToDisk(reply, ok);
if (ok) {
qDebug() << "Saved download file to desk.";
QString hash = getFileHash(filename);
if (expectedHash_.size() && expectedHash_ != hash) {
qCritical() << "Hash mismatch for downloaded file";
emit onDownloadFailed("Update download failed: hash validation failed");
} else {
qDebug() << "Hash is ok for downloaded file";
emit onDownloadFinished(filename, hash);
}
} else {
qCritical() << "Failed to save download file: " << saveError_;
emit onDownloadFailed(saveError_);
}
}
expectedHash_ = "";
}
QString Downloader::saveToDisk(QIODevice *reply, bool &result)
{
qDebug() << "Saving download file to disk.";
QTemporaryFile file(QDir::tempPath() + QDir::separator() + "XXXXXX_YATE.zip");
if (!file.open()) {
saveError_ = file.errorString();
result = false;
return "";
}
file.setAutoRemove(false);
file.write(reply->readAll());
file.close();
saveError_ = "";
result = true;
return file.fileName();
}
#ifndef QT_NO_SSL
void Downloader::onSslErrors(QList<QSslError> errs)
{
for(auto &e: errs) {
qCritical() << e.errorString();
}
}
#endif
void Downloader::download(QString urlString, QString expectedHash)
{
if (isDownloading_.loadRelaxed() != 1) {
qDebug() << "Downloading " << urlString;
QUrl url = QUrl::fromEncoded(urlString.toLocal8Bit());
isDownloading_.storeRelaxed(1);
expectedHash_ = expectedHash;
QNetworkRequest request(url);
QNetworkReply *reply = manager_->get(request);
#ifndef QT_NO_SSL
connect(reply, &QNetworkReply::sslErrors, this, &Downloader::onSslErrors);
#endif
} else {
qWarning() << "Already downloading..";
}
}
QString Downloader::getFileHash(QString filePath)
{
QFile f(filePath);
if (f.open(QFile::ReadOnly)) {
QCryptographicHash hash(QCryptographicHash::Md5);
if (hash.addData(&f)) {
return hash.result().toHex();
}
}
return "";
}
}