Mercurial > trustbridge
view ui/downloader.cpp @ 52:d73a2f0170d4
Add test for another certificate
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Mon, 17 Mar 2014 11:38:42 +0000 |
parents | d28e2624c1d5 |
children | 09cd242d8443 |
line wrap: on
line source
#include "downloader.h" #ifndef DOWNLOAD_SERVER #define DOWNLOAD_SERVER "https://www.intevation.de" #endif #include <QFile> #include <QDir> #include <QDebug> #include <QStandardPaths> #include <QTextStream> #include <QLocale> #include <QSaveFile> #include <polarssl/net.h> #include <polarssl/ssl.h> #include <polarssl/entropy.h> #include <polarssl/ctr_drbg.h> #include <polarssl/error.h> #include <polarssl/certs.h> #define MAX_SW_SIZE 10485760 #define MAX_LIST_SIZE 1048576 Downloader::Downloader(QObject* parent, const QString& url, const QByteArray& certificate, const QDateTime& newestSW, const QDateTime& newestList, const QString& resourceSW, const QString& resourceList): QThread(parent), mLastModSW(newestSW), mLastModList(newestList), mResourceSW(resourceSW), mResourceList(resourceList), mSSLConnection(url, certificate) { } Downloader::~Downloader() { } QString Downloader::getDataDirectory() { QString candidate = QStandardPaths::writableLocation(QStandardPaths::DataLocation); if (candidate.isEmpty()) { qDebug() << "Could not find writeable locaction for me"; return QString(); } QDir cDir(candidate); if (!cDir.exists()) { if (!cDir.mkpath(candidate)) { qDebug() << "Could not create path to: " << candidate; return QString(); } } return cDir.absolutePath(); } QDateTime Downloader::getLastModifiedHeader(const QString &resource) { int ret = -1; QByteArray response; QTextStream responseStream(&response); QLocale cLocale = QLocale::c(); QString headRequest = QString::fromLatin1("HEAD %1 HTTP/1.0\r\n\r\n").arg(resource); ret = mSSLConnection.write(headRequest.toUtf8()); if (ret != 0) { emit error (tr("Connection lost"), SSLConnection::ConnectionLost); return QDateTime(); } response = mSSLConnection.read(1024); if (response.isNull()) { qDebug() << "No response"; emit error (tr("Connection lost"), SSLConnection::ConnectionLost); return QDateTime(); } while (1) { QString line = responseStream.readLine(); if (line.isNull()) { break; } if (line.startsWith("Last-Modified:")) { QDateTime candidate = cLocale.toDateTime(line, "'Last-Modified: 'ddd, dd MMM yyyy HH:mm:ss' GMT'"); qDebug() << "Parsed line : " << line << " to " << candidate; if (candidate.isValid()) { return candidate; } } } qDebug() << "Response: " << response; emit error (tr("Invalid response from the server"), SSLConnection::InvalidResponse); return QDateTime(); } bool Downloader::downloadFile(const QString &resource, const QString &fileName, size_t maxSize) { int ret = -1; size_t bytesRead = 0; QString getRequest = QString::fromLatin1("GET %1 HTTP/1.0\r\n\r\n").arg(resource); QSaveFile outputFile(fileName); ret = mSSLConnection.write(getRequest.toUtf8()); // Open / Create the file to write to. if (!outputFile.open(QIODevice::WriteOnly)) { qDebug() << "Failed to open file"; return false; } if (ret != 0) { emit error(tr("Connection lost"), SSLConnection::ConnectionLost); return false; } do { /* Read the response in 8KiB chunks */ QByteArray response = mSSLConnection.read(8192); if (response.isNull()) { qDebug() << "Error reading response"; emit error(tr("Connection lost"), SSLConnection::ConnectionLost); return false; } outputFile.write(response); qDebug() << "Wrote: "<< response.size(); bytesRead += response.size(); if (response.size() < 8192) { /* Nothing more to read for us */ break; } } while (bytesRead < maxSize); return outputFile.commit(); } void Downloader::run() { int ret; QDateTime remoteModList; QDateTime remoteModSW; if (!mSSLConnection.initialized()) { emit error(tr("Failed to initialize SSL Module."), SSLConnection::ErrUnknown); return; } ret = mSSLConnection.connect(); if (ret != 0) { emit error(tr("Failed to connect."), mSSLConnection.getLastError()); return; } emit progress(tr("Connected"), 1, -1); remoteModSW = getLastModifiedHeader(mResourceSW); remoteModList = getLastModifiedHeader(mResourceList); if (!remoteModSW.isValid() || !remoteModList.isValid()) { qDebug() << "Could not read headers"; return; } if (!mLastModSW.isValid() || remoteModSW > mLastModSW) { QString dataDirectory = getDataDirectory(); if (dataDirectory.isEmpty()) { qDebug() << "Failed to get data directory"; return; } QString fileName = dataDirectory.append("/SW-") .append(remoteModSW.toString("yyyymmddHHmmss")) .append(".exe"); qDebug() << "fileName: " << fileName; if (!downloadFile(mResourceSW, fileName, MAX_SW_SIZE)) { return; } emit newSoftwareAvailable(fileName, remoteModSW); } else if (!mLastModList.isValid() || remoteModList > mLastModList) { QString dataDirectory = getDataDirectory(); if (dataDirectory.isEmpty()) { qDebug() << "Failed to get data directory"; return; } QString fileName = dataDirectory.append("/list-") .append(remoteModSW.toString("yyyymmddHHmmss")) .append(".txt"); qDebug() << "fileName: " << fileName; if (!downloadFile(mResourceList, fileName, MAX_LIST_SIZE)) { return; } emit newListAvailable(fileName, remoteModList); } emit progress(tr("Closing"), 1, -1); }