Mercurial > trustbridge
comparison ui/downloader.cpp @ 910:eaed02defe6a
More SSLConnection refactoring. Fixes curl downloader.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 18 Aug 2014 18:51:33 +0200 |
parents | d1c951b3012d |
children | 75085f7adc78 |
comparison
equal
deleted
inserted
replaced
909:18e3ad073b38 | 910:eaed02defe6a |
---|---|
76 } | 76 } |
77 } | 77 } |
78 return cDir.absolutePath(); | 78 return cDir.absolutePath(); |
79 } | 79 } |
80 | 80 |
81 QMap<QString, QString> Downloader::parseHeaders(QByteArray *data) | |
82 { | |
83 int bodyStart = data->indexOf("\r\n\r\n"); | |
84 QMap<QString, QString> retval; | |
85 QByteArray headers; | |
86 QString response(*data); | |
87 if (bodyStart == -1) { | |
88 qDebug() << "Could not find header end."; | |
89 emit error(tr("Invalid response"), | |
90 SSLConnection::InvalidResponse); | |
91 return retval; | |
92 } | |
93 | |
94 /* Take the headers with one additional line break */ | |
95 headers = data->left(bodyStart + 2); | |
96 /* Chop off the head */ | |
97 | |
98 foreach (const QString& line, response.split("\r\n")) { | |
99 int sepPos = -1; | |
100 sepPos = line.indexOf(": "); | |
101 if (sepPos == -1) { | |
102 continue; | |
103 } | |
104 QString key = line.left(sepPos); | |
105 QString value = line.right(line.size() - sepPos - 2); | |
106 | |
107 retval.insert(key, value); | |
108 } | |
109 | |
110 *data = data->right(data->size() - bodyStart - 4); | |
111 return retval; | |
112 } | |
113 | |
114 QDateTime Downloader::getLastModifiedHeader(const QString &resource) { | |
115 int ret = -1; | |
116 QByteArray response; | |
117 QLocale cLocale = QLocale::c(); | |
118 QMap<QString, QString> headers; | |
119 QString headRequest = | |
120 QString::fromLatin1("HEAD %1 HTTP/1.0\r\n\r\n").arg(resource); | |
121 | |
122 ret = mSSLConnection->write(headRequest.toUtf8()); | |
123 if (ret != 0) { | |
124 emit error (tr("Connection lost"), SSLConnection::ConnectionLost); | |
125 return QDateTime(); | |
126 } | |
127 | |
128 response = mSSLConnection->read(1024); | |
129 | |
130 qDebug() << "Response from server was: " << response; | |
131 | |
132 if (response.isNull()) { | |
133 qDebug() << "No response"; | |
134 emit error (tr("Connection lost"), SSLConnection::ConnectionLost); | |
135 return QDateTime(); | |
136 } | |
137 | |
138 headers = parseHeaders(&response); | |
139 const QString lastModified = headers.value("Last-Modified"); | |
140 if (!lastModified.isEmpty()) { | |
141 QDateTime candidate = cLocale.toDateTime(lastModified, | |
142 "ddd, dd MMM yyyy HH:mm:ss' GMT'"); | |
143 if (candidate.isValid()) { | |
144 return candidate; | |
145 } | |
146 } | |
147 emit error (tr("Invalid response from the server"), SSLConnection::InvalidResponse); | |
148 return QDateTime(); | |
149 } | |
150 | |
151 bool Downloader::downloadFile(const QString &resource, | |
152 const QString &fileName, | |
153 size_t maxSize) | |
154 { | |
155 int ret = -1; | |
156 size_t bytesRead = 0; | |
157 QString getRequest = | |
158 QString::fromLatin1("GET %1 HTTP/1.0\r\n\r\n").arg(resource); | |
159 | |
160 QSaveFile outputFile(fileName); | |
161 | |
162 ret = mSSLConnection->write(getRequest.toUtf8()); | |
163 | |
164 // Open / Create the file to write to. | |
165 if (!outputFile.open(QIODevice::WriteOnly)) { | |
166 qDebug() << "Failed to open file"; | |
167 return false; | |
168 } | |
169 | |
170 if (ret != 0) { | |
171 emit error(tr("Connection lost"), SSLConnection::ConnectionLost); | |
172 return false; | |
173 } | |
174 | |
175 bool inBody = false; | |
176 QMap <QString, QString> headers; | |
177 do { | |
178 /* Read the response in 8KiB chunks */ | |
179 int responseSize = 0; | |
180 QByteArray response = mSSLConnection->read(8192); | |
181 if (response.isNull()) { | |
182 qDebug() << "Error reading response"; | |
183 emit error(tr("Connection lost"), SSLConnection::ConnectionLost); | |
184 return false; | |
185 } | |
186 responseSize = response.size(); | |
187 if (!inBody) { | |
188 headers = parseHeaders(&response); | |
189 inBody = true; | |
190 } | |
191 outputFile.write(response); | |
192 bytesRead += responseSize; | |
193 if (responseSize < 8192) { | |
194 /* Nothing more to read */ | |
195 break; | |
196 } | |
197 /* TODO Emit progress */ | |
198 } while (bytesRead < maxSize); | |
199 | |
200 return outputFile.commit(); | |
201 } | |
202 | 81 |
203 void Downloader::run() { | 82 void Downloader::run() { |
204 int ret; | 83 int ret; |
205 QDateTime remoteModList; | 84 QDateTime remoteModList; |
206 QDateTime remoteModSW; | 85 QDateTime remoteModSW; |
218 return; | 97 return; |
219 } | 98 } |
220 | 99 |
221 emit progress(tr("Connected"), 1, -1); | 100 emit progress(tr("Connected"), 1, -1); |
222 | 101 |
223 remoteModSW = getLastModifiedHeader(mResourceSW); | 102 remoteModSW = mSSLConnection->getLastModifiedHeader(mResourceSW); |
224 emit lastModifiedDate(remoteModSW); | 103 emit lastModifiedDate(remoteModSW); |
225 | 104 |
226 if (!remoteModSW.isValid()) { | 105 if (!remoteModSW.isValid()) { |
106 emit error (tr("Connection failed."), SSLConnection::InvalidResponse); | |
227 qDebug() << "Could not parse headers for Software"; | 107 qDebug() << "Could not parse headers for Software"; |
228 return; | 108 return; |
229 } | 109 } |
230 | 110 |
231 if (!mLastModSW.isValid() || remoteModSW > mLastModSW) { | 111 if (!mLastModSW.isValid() || remoteModSW > mLastModSW) { |
245 #endif | 125 #endif |
246 | 126 |
247 qDebug() << "fileName: " << fileName; | 127 qDebug() << "fileName: " << fileName; |
248 | 128 |
249 if (mDownloadSW) { | 129 if (mDownloadSW) { |
250 if (!downloadFile(mResourceSW, fileName, MAX_SW_SIZE)) { | 130 if (!mSSLConnection->downloadFile(mResourceSW, fileName, MAX_SW_SIZE)) { |
131 emit error(tr("Failed to download File"), SSLConnection::ConnectionLost); | |
251 qDebug() << "Failed to download software update."; | 132 qDebug() << "Failed to download software update."; |
252 return; | 133 return; |
253 } | 134 } |
254 QFile::setPermissions(fileName, QFileDevice::ReadOwner | | 135 QFile::setPermissions(fileName, QFileDevice::ReadOwner | |
255 QFileDevice::WriteOwner | | 136 QFileDevice::WriteOwner | |
258 | 139 |
259 emit newSoftwareAvailable(fileName, remoteModSW); | 140 emit newSoftwareAvailable(fileName, remoteModSW); |
260 return; | 141 return; |
261 } | 142 } |
262 | 143 |
263 remoteModList = getLastModifiedHeader(mResourceList); | 144 remoteModList = mSSLConnection->getLastModifiedHeader(mResourceList); |
264 if (!remoteModList.isValid()) { | 145 if (!remoteModList.isValid()) { |
146 emit error (tr("Connection failed."), SSLConnection::InvalidResponse); | |
265 qDebug() << "Could not parse headers for List"; | 147 qDebug() << "Could not parse headers for List"; |
266 return; | 148 return; |
267 } | 149 } |
268 | 150 |
269 if (!mLastModList.isValid() || remoteModList > mLastModList) { | 151 if (!mLastModList.isValid() || remoteModList > mLastModList) { |
278 .append(remoteModList.toString("yyyyMMddHHmmss")) | 160 .append(remoteModList.toString("yyyyMMddHHmmss")) |
279 .append(".txt"); | 161 .append(".txt"); |
280 | 162 |
281 qDebug() << "fileName: " << fileName; | 163 qDebug() << "fileName: " << fileName; |
282 | 164 |
283 if (!downloadFile(mResourceList, fileName, MAX_LIST_SIZE)) { | 165 if (!mSSLConnection->downloadFile(mResourceList, fileName, MAX_LIST_SIZE)) { |
284 return; | 166 return; |
285 } | 167 } |
286 | 168 |
287 emit newListAvailable(fileName, remoteModList); | 169 emit newListAvailable(fileName, remoteModList); |
288 } | 170 } |