diff ui/downloader_win.cpp @ 17:c12825a651ed

Read out content-length and use this to skip existing files
author Andre Heinecke <aheinecke@intevation.de>
date Wed, 19 Feb 2014 14:22:26 +0000
parents 95e1b6edf2fc
children f4f957c58e0a
line wrap: on
line diff
--- a/ui/downloader_win.cpp	Wed Feb 19 10:45:29 2014 +0000
+++ b/ui/downloader_win.cpp	Wed Feb 19 14:22:26 2014 +0000
@@ -21,12 +21,18 @@
 #include <QDebug>
 #include <QDateTime>
 #include <QSaveFile>
+#include <QFileInfo>
 
 #define DEBUG if (1) qDebug() << __PRETTY_FUNCTION__
 
 #define MAX_SW_SIZE 10485760
 #define MAX_LIST_SIZE 1048576
 
+
+#define LIST_RESOURCE "/incoming/aheinecke/test"
+#define SW_RESOURCE "/incoming/aheinecke/test"
+
+
 /** @brief Qt wrapper around FormatMessage
  *
  * @returns The error message of the error that occurred
@@ -281,16 +287,18 @@
 }
 
 bool Downloader::downloadFile(HINTERNET hSession, HINTERNET hConnect,
-        LPCWSTR resource, const QString &filename, DWORD maxSize)
+        LPCWSTR resource, const QString &fileName, DWORD maxSize)
 {
     HINTERNET hRequest = NULL;
     bool retval = false;
     DWORD bytesAvailable = 0,
           err = 0,
           bytesRead = 0,
-          totalDownloaded = 0;
+          totalDownloaded = 0,
+          contentLength = 0,
+          sizeOfDWORD = sizeof (DWORD);
 
-    QSaveFile outputFile(filename);
+    QSaveFile outputFile(fileName);
 
     if (!hSession || !hConnect || !resource) {
         SetLastError(ERROR_INVALID_PARAMETER);
@@ -322,6 +330,36 @@
         // TODO error out
     }
 
+
+    if (!(WinHttpQueryHeaders(hRequest,
+                              WINHTTP_QUERY_CONTENT_LENGTH |
+                              WINHTTP_QUERY_FLAG_NUMBER,
+                              NULL,
+                              &contentLength,
+                              &sizeOfDWORD,
+                              WINHTTP_NO_HEADER_INDEX))) {
+        // Continue anyway as we later really check how
+        // much we download.
+        DEBUG << "No content-length";
+    }
+
+    if (contentLength > maxSize) {
+        err = ERROR_INVALID_DATA;
+        goto cleanup;
+    }
+
+    if (contentLength) {
+        QFileInfo finf(fileName);
+        if (finf.exists() && finf.isReadable() &&
+                finf.size() == contentLength) {
+            // We already have data of the same size
+            // No need to waste bandwidth.
+            DEBUG << "Skipping download because file exists";
+            retval = true;
+            goto cleanup;
+        }
+    }
+
     // Open / Create the file to write to.
     if (!outputFile.open(QIODevice::WriteOnly)) {
         DEBUG << "Failed to open file";
@@ -329,6 +367,7 @@
         goto cleanup;
     }
 
+    DEBUG << "output file size: " << outputFile.size();
     do
     {
         char outBuf[8192]; // 8KB is the internal buffer size of winhttp
@@ -350,6 +389,7 @@
         if (bytesAvailable > maxSize) {
             DEBUG << "File to large";
             retval = false;
+            err = ERROR_INVALID_DATA;
             break;
         }
 
@@ -360,8 +400,6 @@
             break;
         } else {
             if (bytesRead) {
-                DEBUG << "Downloaded: " << bytesRead << "B";
-
                 // Write data to file.
                 if (outputFile.write(outBuf, bytesRead) !=
                         bytesRead) {
@@ -392,7 +430,7 @@
 
 cleanup:
 
-    if (retval) {
+    if (retval && outputFile.isOpen()) {
         // Actually save the file to disk / move to homedir
         retval = outputFile.commit();
     }
@@ -440,10 +478,10 @@
 
 
     lastModifiedSoftware = getLastModifiedHeader(hSession, hConnect,
-            L"/incoming/aheinecke/test");
+            L""SW_RESOURCE);
 
     lastModifiedList = getLastModifiedHeader(hSession, hConnect,
-            L"/incoming/aheinecke/test");
+            L""LIST_RESOURCE);
 
     if (!lastModifiedList.isValid() || !lastModifiedSoftware.isValid()) {
         DEBUG << "Could not read headers: " << getLastErrorMsg();
@@ -462,9 +500,9 @@
             .append(lastModifiedSoftware.toString("yyyymmddHHmmss"))
             .append(".exe");
 
-        DEBUG << "Filename: " << fileName;
+        DEBUG << "fileName: " << fileName;
 
-        if (!downloadFile(hSession, hConnect, L"/incoming/aheinecke/test",
+        if (!downloadFile(hSession, hConnect, L""SW_RESOURCE,
                    fileName, MAX_SW_SIZE)) {
             DEBUG << "Error downloading File: " << getLastErrorMsg();
             goto cleanup;
@@ -483,9 +521,9 @@
             .append(lastModifiedSoftware.toString("yyyymmddHHmmss"))
             .append(".txt");
 
-        DEBUG << "Filename: " << fileName;
+        DEBUG << "fileName: " << fileName;
 
-        if (!downloadFile(hSession, hConnect, L"/incoming/aheinecke/test",
+        if (!downloadFile(hSession, hConnect, L""LIST_RESOURCE,
                    fileName, MAX_LIST_SIZE)) {
             DEBUG << "Error downloading File: " << getLastErrorMsg();
             goto cleanup;

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