changeset 10:fe39d93f1261

Start on Downloader component
author Andre Heinecke <aheinecke@intevation.de>
date Thu, 13 Feb 2014 14:43:15 +0000
parents 2ad9a96518e3
children 7e2f14c7aba2
files ui/certificatelist.h ui/downloader.cpp ui/downloader.h ui/mainwindow.cpp
diffstat 4 files changed, 210 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- /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 <windows.h>
+#include <winhttp.h>
+#endif
+
+#include <QFile>
+#include <QDebug>
+
+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);
+    }
+}
--- /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 <QThread>
+#include <QString>
+#include <QByteArray>
+
+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
--- 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 <QApplication>
 
 #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()

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