# HG changeset patch # User Andre Heinecke # Date 1392302595 0 # Node ID fe39d93f12617c582a7d5d8fb5d3e7fe39f414d3 # Parent 2ad9a96518e39762bc5b87bb9d87fc794721557d Start on Downloader component diff -r 2ad9a96518e3 -r fe39d93f1261 ui/certificatelist.h --- a/ui/certificatelist.h Wed Feb 12 18:45:13 2014 +0000 +++ b/ui/certificatelist.h Thu Feb 13 14:43:15 2014 +0000 @@ -10,9 +10,6 @@ * check the Status afterwards to see if the file * could be parsed. * - * The certificate list will be kept in memory until - * this object is destroyed. - * */ class QByteArray; diff -r 2ad9a96518e3 -r fe39d93f1261 ui/downloader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/downloader.cpp Thu Feb 13 14:43:15 2014 +0000 @@ -0,0 +1,119 @@ +#include "downloader.h" + +#ifndef MYVERSION +#define MYVERSION "1" +#endif + +#ifndef DOWNLOAD_SERVER +#define DOWNLOAD_SERVER "https://www.intevation.de" +#endif + +#ifdef Q_OS_WIN +#include +#include +#endif + +#include +#include + +Downloader::Downloader(QObject* parent, const QString& url) +{ + Downloader (parent, url, QFile(":Certificates/https").readAll()); +} + +Downloader::Downloader(QObject* parent, const QString& url, + const QByteArray& certificate) : + mUrl(url), + mCert(certificate), + QThread(parent) +{ +} + +void Downloader::run() { +#ifdef Q_OS_WIN + // We use WinAPI here instead of Qt because we want to avoid + // QtNetworks SSL stack which is based on OpenSSL and so + // we might be incompatible with GPL code. Also using the + // native API means that the security of the SSL implementation + // is tied to the security of the system. + BOOL bResults = FALSE; + HINTERNET hSession = NULL, + hConnect = NULL, + hRequest = NULL; + SYSTEMTIME lastModified; + DWORD sizeOfSystemtime = sizeof (SYSTEMTIME); + + // Get a syncronous session handle + hSession = WinHttpOpen(L"M13 "MYVERSION, + WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, + WINHTTP_NO_PROXY_NAME, + WINHTTP_NO_PROXY_BYPASS, 0); + + if (hSession) { + // Initialize connection. No request is done here. + hConnect = WinHttpConnect(hSession, L""DOWNLOAD_SERVER, + INTERNET_DEFAULT_HTTPS_PORT, 0); + + } + + if (hConnect) { + // Make a head request + hRequest = WinHttpOpenRequest(hConnect, L"HEAD", + L"/index.html", + NULL, WINHTTP_NO_REFERER, + WINHTTP_DEFAULT_ACCEPT_TYPES, + 0); + } + + if (hRequest) { + bResults = WinHttpSendRequest(hRequest, + WINHTTP_NO_ADDITIONAL_HEADERS, + 0, WINHTTP_NO_REQUEST_DATA, 0, + 0, 0); + } + + if (bResults) { + bResults = WinHttpReceiveResponse(hRequest, NULL); + } + + + + if (bResults) { + bResults = WinHttpQueryHeaders(hRequest, + WINHTTP_QUERY_LAST_MODIFIED | + WINHTTP_QUERY_FLAG_SYSTEMTIME, + NULL, + &lastModified, + &sizeOfSystemtime, + WINHTTP_NO_HEADER_INDEX ); + } + + qDebug() << "Last modified year: " << lastModified.wYear; + + + if (!bResults) { + // Report any errors. + qDebug() << "Error" << GetLastError(); + emit error(tr("Unknown Problem when connecting"), Unknown); + } + + // Cleanup + if (hRequest) { + WinHttpCloseHandle(hRequest); + } + + if (hConnect) { + WinHttpCloseHandle(hConnect); + + } + + if (hSession) { + WinHttpCloseHandle(hSession); + } +#endif + + for (int i=0; i< 10; i++) { + qDebug("Going to sleep\n"); + sleep(10); + } +} diff -r 2ad9a96518e3 -r fe39d93f1261 ui/downloader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/downloader.h Thu Feb 13 14:43:15 2014 +0000 @@ -0,0 +1,87 @@ +#ifndef DOWNLOADER_H +#define DOWNLOADER_H +/** + * @file downloader.h + * @brief High level API to download necessary data. + * + */ + +#include +#include +#include + +class Downloader: public QThread +{ + Q_OBJECT + +public: + /** + * @brief Construct a downloader to download data from url + * + * Takes the builtin certificate for https verification. + * + * @param[in] parent the parent object. + * @param[in] url the Url to download data from. + */ + Downloader(QObject* parent, const QString& url); + + /** + * @brief Construct a downloader with a specific certificate + * + * @param[in] parent the parent object. + * @param[in] url the Url to download data from + * @param[in] certificate to accept https connection from + */ + Downloader(QObject* parent, const QString& url, + const QByteArray& certificate); + + enum Status { + NewSoftwareAvailable, // A Software Update has been downloaded + NewListAvailable, // A certificate list has been downloaded + UpToDate, // Nothing changed + Error // An error happened + }; + + enum ErrorCode { + NoConnection, + InvalidCertificate, + ConnectionLost, + Timeout, + Unknown + }; + + /** + * @brief Construct a downloader with a specific certificate + * + * @param[in] url the Url to download data from + * @param[in] certificate to accept https connection from + */ + QString getDownloadedFileName(); + +protected: + void run(); + +private: + QString mUrl; + QByteArray mCert; + +Q_SIGNALS: + /** + * @brief Some progress has been made. + * + * @param[out] message: A message to show. Can be empty. + * @param[out] current: Value of current progress. + * @param[out] total: Total value of possible progress + */ + void progress(const QString &message, int current, int total); + + /** + * @brief An error happened + * + * @param[out] message: A message to show. Can be empty. + * @param[out] errorCode: ErrorCode of this error. + * @param[out] total: Total value of possible progress. + */ + void error(const QString &message, ErrorCode error); +}; +#endif diff -r 2ad9a96518e3 -r fe39d93f1261 ui/mainwindow.cpp --- a/ui/mainwindow.cpp Wed Feb 12 18:45:13 2014 +0000 +++ b/ui/mainwindow.cpp Thu Feb 13 14:43:15 2014 +0000 @@ -9,6 +9,7 @@ #include #include "certificatelist.h" +#include "downloader.h" MainWindow::MainWindow() { createActions(); @@ -35,14 +36,14 @@ void MainWindow::showMessage() { - CertificateList * myCertList = new CertificateList((char*)"foo"); mTrayIcon->showMessage("Hello", "World", QSystemTrayIcon::Information, 10000); } void MainWindow::manualCheck() { - QMessageBox::information(0, "Yay", - "It Woarx.\n"); + Downloader* downloader = new Downloader(this, QString::fromLatin1("")); + connect(downloader, &Downloader::finished, downloader, &QObject::deleteLater); + downloader->start(); } void MainWindow::createActions()