annotate ui/downloader.cpp @ 908:d1c951b3012d

Curl based implementation of sslconnection
author Andre Heinecke <andre.heinecke@intevation.de>
date Wed, 13 Aug 2014 19:35:08 +0200
parents 4b702f6cf9b6
children eaed02defe6a
rev   line source
404
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 76
diff changeset
1 /* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 76
diff changeset
2 * Software engineering by Intevation GmbH
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 76
diff changeset
3 *
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 76
diff changeset
4 * This file is Free Software under the GNU GPL (v>=2)
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 76
diff changeset
5 * and comes with ABSOLUTELY NO WARRANTY!
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 76
diff changeset
6 * See LICENSE.txt for details.
17e1c8f37d72 Add License
Andre Heinecke <aheinecke@intevation.de>
parents: 76
diff changeset
7 */
10
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
8 #include "downloader.h"
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
9
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
10 #ifndef DOWNLOAD_SERVER
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
11 #define DOWNLOAD_SERVER "https://www.intevation.de"
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
12 #endif
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
13
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
14 #include <QFile>
15
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
15 #include <QDir>
10
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
16 #include <QDebug>
15
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
17 #include <QStandardPaths>
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
18 #include <QLocale>
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
19 #include <QSaveFile>
27
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
20
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
21 #include <polarssl/net.h>
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
22 #include <polarssl/ssl.h>
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
23 #include <polarssl/entropy.h>
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
24 #include <polarssl/ctr_drbg.h>
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
25 #include <polarssl/error.h>
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
26 #include <polarssl/certs.h>
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
27
808
13cf42dbe9bd Increase MAX SW size to 15mb
Andre Heinecke <andre.heinecke@intevation.de>
parents: 553
diff changeset
28 #define MAX_SW_SIZE 15728640
27
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
29 #define MAX_LIST_SIZE 1048576
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
30
908
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
31 #include "sslconnection_curl.h"
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
32 #include "sslconnection_bare.h"
10
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
33
15
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
34 Downloader::Downloader(QObject* parent, const QString& url,
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
35 const QByteArray& certificate,
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
36 const QDateTime& newestSW,
45
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents: 35
diff changeset
37 const QDateTime& newestList,
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents: 35
diff changeset
38 const QString& resourceSW,
460
f8bed9008362 Added switch to download new available software.
Raimund Renkert <rrenkert@intevation.de>
parents: 459
diff changeset
39 const QString& resourceList,
f8bed9008362 Added switch to download new available software.
Raimund Renkert <rrenkert@intevation.de>
parents: 459
diff changeset
40 bool downloadSW):
12
9121eea6d93f Fix constructor usage. Too much Java.
Andre Heinecke <aheinecke@intevation.de>
parents: 11
diff changeset
41 QThread(parent),
15
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
42 mLastModSW(newestSW),
27
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
43 mLastModList(newestList),
45
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents: 35
diff changeset
44 mResourceSW(resourceSW),
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents: 35
diff changeset
45 mResourceList(resourceList),
908
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
46 mDownloadSW(downloadSW)
10
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
47 {
908
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
48 #ifdef USE_CURL
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
49 mSSLConnection = new SSLConnectionCurl(url, certificate);
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
50 #else
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
51 mSSLConnection = new SSLConnectionBare(url, certificate);
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
52 #endif
27
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
53 }
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
54
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
55
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
56 Downloader::~Downloader() {
908
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
57 delete mSSLConnection;
10
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
58 }
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
59
15
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
60 QString Downloader::getDataDirectory()
10
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
61 {
15
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
62 QString candidate =
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
63 QStandardPaths::writableLocation(QStandardPaths::DataLocation);
12
9121eea6d93f Fix constructor usage. Too much Java.
Andre Heinecke <aheinecke@intevation.de>
parents: 11
diff changeset
64
15
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
65 if (candidate.isEmpty()) {
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
66 qDebug() << "Could not find writeable locaction for me";
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
67 return QString();
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
68 }
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
69
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
70 QDir cDir(candidate);
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
71
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
72 if (!cDir.exists()) {
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
73 if (!cDir.mkpath(candidate)) {
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
74 qDebug() << "Could not create path to: " << candidate;
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
75 return QString();
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
76 }
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
77 }
95e1b6edf2fc Implement more downloader functionality for Windows
Andre Heinecke <aheinecke@intevation.de>
parents: 12
diff changeset
78 return cDir.absolutePath();
10
fe39d93f1261 Start on Downloader component
Andre Heinecke <aheinecke@intevation.de>
parents:
diff changeset
79 }
27
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
80
54
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
81 QMap<QString, QString> Downloader::parseHeaders(QByteArray *data)
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
82 {
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
83 int bodyStart = data->indexOf("\r\n\r\n");
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
84 QMap<QString, QString> retval;
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
85 QByteArray headers;
76
63b79d135631 Remove QTextStream usage. The QTextStream usage in this way
Andre Heinecke <aheinecke@intevation.de>
parents: 72
diff changeset
86 QString response(*data);
54
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
87 if (bodyStart == -1) {
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
88 qDebug() << "Could not find header end.";
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
89 emit error(tr("Invalid response"),
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
90 SSLConnection::InvalidResponse);
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
91 return retval;
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
92 }
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
93
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
94 /* Take the headers with one additional line break */
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
95 headers = data->left(bodyStart + 2);
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
96 /* Chop off the head */
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
97
76
63b79d135631 Remove QTextStream usage. The QTextStream usage in this way
Andre Heinecke <aheinecke@intevation.de>
parents: 72
diff changeset
98 foreach (const QString& line, response.split("\r\n")) {
54
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
99 int sepPos = -1;
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
100 sepPos = line.indexOf(": ");
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
101 if (sepPos == -1) {
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
102 continue;
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
103 }
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
104 QString key = line.left(sepPos);
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
105 QString value = line.right(line.size() - sepPos - 2);
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
106
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
107 retval.insert(key, value);
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
108 }
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
109
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
110 *data = data->right(data->size() - bodyStart - 4);
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
111 return retval;
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
112 }
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
113
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
114 QDateTime Downloader::getLastModifiedHeader(const QString &resource) {
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
115 int ret = -1;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
116 QByteArray response;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
117 QLocale cLocale = QLocale::c();
54
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
118 QMap<QString, QString> headers;
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
119 QString headRequest =
46
d28e2624c1d5 Reset connection before the next request.
Andre Heinecke <aheinecke@intevation.de>
parents: 45
diff changeset
120 QString::fromLatin1("HEAD %1 HTTP/1.0\r\n\r\n").arg(resource);
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
121
908
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
122 ret = mSSLConnection->write(headRequest.toUtf8());
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
123 if (ret != 0) {
45
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents: 35
diff changeset
124 emit error (tr("Connection lost"), SSLConnection::ConnectionLost);
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
125 return QDateTime();
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
126 }
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
127
908
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
128 response = mSSLConnection->read(1024);
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
129
553
cb044efdaf0d Debugging: Always log the complete response
Andre Heinecke <aheinecke@intevation.de>
parents: 485
diff changeset
130 qDebug() << "Response from server was: " << response;
cb044efdaf0d Debugging: Always log the complete response
Andre Heinecke <aheinecke@intevation.de>
parents: 485
diff changeset
131
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
132 if (response.isNull()) {
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
133 qDebug() << "No response";
45
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents: 35
diff changeset
134 emit error (tr("Connection lost"), SSLConnection::ConnectionLost);
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
135 return QDateTime();
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
136 }
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
137
54
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
138 headers = parseHeaders(&response);
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
139 const QString lastModified = headers.value("Last-Modified");
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
140 if (!lastModified.isEmpty()) {
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
141 QDateTime candidate = cLocale.toDateTime(lastModified,
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
142 "ddd, dd MMM yyyy HH:mm:ss' GMT'");
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
143 if (candidate.isValid()) {
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
144 return candidate;
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
145 }
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
146 }
45
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents: 35
diff changeset
147 emit error (tr("Invalid response from the server"), SSLConnection::InvalidResponse);
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
148 return QDateTime();
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
149 }
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
150
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
151 bool Downloader::downloadFile(const QString &resource,
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
152 const QString &fileName,
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
153 size_t maxSize)
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
154 {
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
155 int ret = -1;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
156 size_t bytesRead = 0;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
157 QString getRequest =
46
d28e2624c1d5 Reset connection before the next request.
Andre Heinecke <aheinecke@intevation.de>
parents: 45
diff changeset
158 QString::fromLatin1("GET %1 HTTP/1.0\r\n\r\n").arg(resource);
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
159
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
160 QSaveFile outputFile(fileName);
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
161
908
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
162 ret = mSSLConnection->write(getRequest.toUtf8());
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
163
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
164 // Open / Create the file to write to.
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
165 if (!outputFile.open(QIODevice::WriteOnly)) {
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
166 qDebug() << "Failed to open file";
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
167 return false;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
168 }
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
169
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
170 if (ret != 0) {
45
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents: 35
diff changeset
171 emit error(tr("Connection lost"), SSLConnection::ConnectionLost);
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
172 return false;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
173 }
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
174
54
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
175 bool inBody = false;
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
176 QMap <QString, QString> headers;
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
177 do {
46
d28e2624c1d5 Reset connection before the next request.
Andre Heinecke <aheinecke@intevation.de>
parents: 45
diff changeset
178 /* Read the response in 8KiB chunks */
54
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
179 int responseSize = 0;
908
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
180 QByteArray response = mSSLConnection->read(8192);
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
181 if (response.isNull()) {
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
182 qDebug() << "Error reading response";
45
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents: 35
diff changeset
183 emit error(tr("Connection lost"), SSLConnection::ConnectionLost);
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
184 return false;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
185 }
54
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
186 responseSize = response.size();
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
187 if (!inBody) {
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
188 headers = parseHeaders(&response);
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
189 inBody = true;
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
190 }
46
d28e2624c1d5 Reset connection before the next request.
Andre Heinecke <aheinecke@intevation.de>
parents: 45
diff changeset
191 outputFile.write(response);
54
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
192 bytesRead += responseSize;
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
193 if (responseSize < 8192) {
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
194 /* Nothing more to read */
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
195 break;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
196 }
54
09cd242d8443 Split out Header parsing into it's own function
Andre Heinecke <aheinecke@intevation.de>
parents: 46
diff changeset
197 /* TODO Emit progress */
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
198 } while (bytesRead < maxSize);
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
199
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
200 return outputFile.commit();
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
201 }
27
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
202
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
203 void Downloader::run() {
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
204 int ret;
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
205 QDateTime remoteModList;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
206 QDateTime remoteModSW;
27
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
207
908
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
208 if (!mSSLConnection->initialized()) {
45
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents: 35
diff changeset
209 emit error(tr("Failed to initialize SSL Module."), SSLConnection::ErrUnknown);
27
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
210 return;
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
211 }
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
212
908
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
213 ret = mSSLConnection->connect();
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
214
27
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
215 if (ret != 0) {
45
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents: 35
diff changeset
216 emit error(tr("Failed to connect."),
908
d1c951b3012d Curl based implementation of sslconnection
Andre Heinecke <andre.heinecke@intevation.de>
parents: 809
diff changeset
217 mSSLConnection->getLastError());
27
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
218 return;
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
219 }
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
220
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
221 emit progress(tr("Connected"), 1, -1);
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
222
45
c6125d73faf4 Move SSLConnection into it's own class
Andre Heinecke <aheinecke@intevation.de>
parents: 35
diff changeset
223 remoteModSW = getLastModifiedHeader(mResourceSW);
485
5834b340c54c Emit a signal for last modified date in downloader.
Raimund Renkert <rrenkert@intevation.de>
parents: 460
diff changeset
224 emit lastModifiedDate(remoteModSW);
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
225
459
34cc448409ec Fix error handling
Andre Heinecke <aheinecke@intevation.de>
parents: 458
diff changeset
226 if (!remoteModSW.isValid()) {
34cc448409ec Fix error handling
Andre Heinecke <aheinecke@intevation.de>
parents: 458
diff changeset
227 qDebug() << "Could not parse headers for Software";
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
228 return;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
229 }
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
230
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
231 if (!mLastModSW.isValid() || remoteModSW > mLastModSW) {
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
232 QString dataDirectory = getDataDirectory();
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
233
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
234 if (dataDirectory.isEmpty()) {
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
235 qDebug() << "Failed to get data directory";
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
236 return;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
237 }
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
238
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
239 QString fileName = dataDirectory.append("/SW-")
442
d2f4e28b5a13 Fix date format for file names
Andre Heinecke <aheinecke@intevation.de>
parents: 404
diff changeset
240 .append(remoteModSW.toString("yyyyMMddHHmmss"))
809
4b702f6cf9b6 Download sofware with .sh extension on linux and make it exeutable
Andre Heinecke <andre.heinecke@intevation.de>
parents: 808
diff changeset
241 #ifdef WIN32
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
242 .append(".exe");
809
4b702f6cf9b6 Download sofware with .sh extension on linux and make it exeutable
Andre Heinecke <andre.heinecke@intevation.de>
parents: 808
diff changeset
243 #else
4b702f6cf9b6 Download sofware with .sh extension on linux and make it exeutable
Andre Heinecke <andre.heinecke@intevation.de>
parents: 808
diff changeset
244 .append(".sh");
4b702f6cf9b6 Download sofware with .sh extension on linux and make it exeutable
Andre Heinecke <andre.heinecke@intevation.de>
parents: 808
diff changeset
245 #endif
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
246
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
247 qDebug() << "fileName: " << fileName;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
248
460
f8bed9008362 Added switch to download new available software.
Raimund Renkert <rrenkert@intevation.de>
parents: 459
diff changeset
249 if (mDownloadSW) {
f8bed9008362 Added switch to download new available software.
Raimund Renkert <rrenkert@intevation.de>
parents: 459
diff changeset
250 if (!downloadFile(mResourceSW, fileName, MAX_SW_SIZE)) {
809
4b702f6cf9b6 Download sofware with .sh extension on linux and make it exeutable
Andre Heinecke <andre.heinecke@intevation.de>
parents: 808
diff changeset
251 qDebug() << "Failed to download software update.";
460
f8bed9008362 Added switch to download new available software.
Raimund Renkert <rrenkert@intevation.de>
parents: 459
diff changeset
252 return;
f8bed9008362 Added switch to download new available software.
Raimund Renkert <rrenkert@intevation.de>
parents: 459
diff changeset
253 }
809
4b702f6cf9b6 Download sofware with .sh extension on linux and make it exeutable
Andre Heinecke <andre.heinecke@intevation.de>
parents: 808
diff changeset
254 QFile::setPermissions(fileName, QFileDevice::ReadOwner |
4b702f6cf9b6 Download sofware with .sh extension on linux and make it exeutable
Andre Heinecke <andre.heinecke@intevation.de>
parents: 808
diff changeset
255 QFileDevice::WriteOwner |
4b702f6cf9b6 Download sofware with .sh extension on linux and make it exeutable
Andre Heinecke <andre.heinecke@intevation.de>
parents: 808
diff changeset
256 QFileDevice::ExeOwner);
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
257 }
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
258
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
259 emit newSoftwareAvailable(fileName, remoteModSW);
458
6fac87cadbd8 Only check for list if now sw is available
Andre Heinecke <aheinecke@intevation.de>
parents: 443
diff changeset
260 return;
6fac87cadbd8 Only check for list if now sw is available
Andre Heinecke <aheinecke@intevation.de>
parents: 443
diff changeset
261 }
6fac87cadbd8 Only check for list if now sw is available
Andre Heinecke <aheinecke@intevation.de>
parents: 443
diff changeset
262
6fac87cadbd8 Only check for list if now sw is available
Andre Heinecke <aheinecke@intevation.de>
parents: 443
diff changeset
263 remoteModList = getLastModifiedHeader(mResourceList);
459
34cc448409ec Fix error handling
Andre Heinecke <aheinecke@intevation.de>
parents: 458
diff changeset
264 if (!remoteModList.isValid()) {
34cc448409ec Fix error handling
Andre Heinecke <aheinecke@intevation.de>
parents: 458
diff changeset
265 qDebug() << "Could not parse headers for List";
34cc448409ec Fix error handling
Andre Heinecke <aheinecke@intevation.de>
parents: 458
diff changeset
266 return;
34cc448409ec Fix error handling
Andre Heinecke <aheinecke@intevation.de>
parents: 458
diff changeset
267 }
458
6fac87cadbd8 Only check for list if now sw is available
Andre Heinecke <aheinecke@intevation.de>
parents: 443
diff changeset
268
6fac87cadbd8 Only check for list if now sw is available
Andre Heinecke <aheinecke@intevation.de>
parents: 443
diff changeset
269 if (!mLastModList.isValid() || remoteModList > mLastModList) {
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
270 QString dataDirectory = getDataDirectory();
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
271
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
272 if (dataDirectory.isEmpty()) {
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
273 qDebug() << "Failed to get data directory";
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
274 return;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
275 }
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
276
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
277 QString fileName = dataDirectory.append("/list-")
443
20f539866fa8 Fixed certificate list file name.
Raimund Renkert <rrenkert@intevation.de>
parents: 442
diff changeset
278 .append(remoteModList.toString("yyyyMMddHHmmss"))
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
279 .append(".txt");
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
280
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
281 qDebug() << "fileName: " << fileName;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
282
46
d28e2624c1d5 Reset connection before the next request.
Andre Heinecke <aheinecke@intevation.de>
parents: 45
diff changeset
283 if (!downloadFile(mResourceList, fileName, MAX_LIST_SIZE)) {
32
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
284 return;
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
285 }
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
286
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
287 emit newListAvailable(fileName, remoteModList);
d8e93fa1fc93 Downloader logic
Andre Heinecke <andre.heinecke@intevation.de>
parents: 27
diff changeset
288 }
27
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
289
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
290 emit progress(tr("Closing"), 1, -1);
62cd56cea09b Start on polarssl Downloader.
Andre Heinecke <andre.heinecke@intevation.de>
parents: 18
diff changeset
291 }

http://wald.intevation.org/projects/trustbridge/