changeset 54:09cd242d8443

Split out Header parsing into it's own function
author Andre Heinecke <aheinecke@intevation.de>
date Mon, 17 Mar 2014 14:48:05 +0000
parents 0aacc291c04b
children 64200b011dfd
files ui/downloader.cpp ui/downloader.h
diffstat 2 files changed, 69 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/ui/downloader.cpp	Mon Mar 17 14:47:18 2014 +0000
+++ b/ui/downloader.cpp	Mon Mar 17 14:48:05 2014 +0000
@@ -63,12 +63,49 @@
     return cDir.absolutePath();
 }
 
+QMap<QString, QString> Downloader::parseHeaders(QByteArray *data)
+{
+    int bodyStart = data->indexOf("\r\n\r\n");
+    QMap<QString, QString> retval;
+    QByteArray headers;
+    QTextStream responseStream(&headers);
+    if (bodyStart == -1) {
+        qDebug() << "Could not find header end.";
+        emit error(tr("Invalid response"),
+                SSLConnection::InvalidResponse);
+        return retval;
+    }
+
+    /* Take the headers with one additional line break */
+    headers = data->left(bodyStart + 2);
+    /* Chop off the head */
+
+    while (1) {
+        QString line = responseStream.readLine();
+        int sepPos = -1;
+        if (line.isNull()) {
+            break;
+        }
+        sepPos = line.indexOf(": ");
+        if (sepPos == -1) {
+            continue;
+        }
+        QString key = line.left(sepPos);
+        QString value = line.right(line.size() - sepPos - 2);
+
+        retval.insert(key, value);
+    }
+
+    *data = data->right(data->size() - bodyStart - 4);
+    return retval;
+}
 
 QDateTime Downloader::getLastModifiedHeader(const QString &resource) {
     int ret = -1;
     QByteArray response;
     QTextStream responseStream(&response);
     QLocale cLocale = QLocale::c();
+    QMap<QString, QString> headers;
     QString headRequest =
         QString::fromLatin1("HEAD %1 HTTP/1.0\r\n\r\n").arg(resource);
 
@@ -86,21 +123,18 @@
         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;
-            }
+    headers = parseHeaders(&response);
+    const QString lastModified = headers.value("Last-Modified");
+    qDebug() << "Headers: " << headers;
+    if (!lastModified.isEmpty()) {
+        QDateTime candidate = cLocale.toDateTime(lastModified,
+                "ddd, dd MMM yyyy HH:mm:ss' GMT'");
+        if (candidate.isValid()) {
+            return candidate;
         }
     }
-    qDebug() << "Response: " << response;
     emit error (tr("Invalid response from the server"), SSLConnection::InvalidResponse);
+    qDebug() << "Response from server was: " << response;
     return QDateTime();
 }
 
@@ -128,21 +162,29 @@
         return false;
     }
 
+    bool inBody = false;
+    QMap <QString, QString> headers;
     do {
         /* Read the response in 8KiB chunks */
+        int responseSize = 0;
         QByteArray response = mSSLConnection.read(8192);
         if (response.isNull()) {
             qDebug() << "Error reading response";
             emit error(tr("Connection lost"), SSLConnection::ConnectionLost);
             return false;
         }
+        responseSize = response.size();
+        if (!inBody) {
+            headers = parseHeaders(&response);
+            inBody = true;
+        }
         outputFile.write(response);
-        qDebug() << "Wrote: "<< response.size();
-        bytesRead += response.size();
-        if (response.size() < 8192) {
-            /* Nothing more to read for us */
+        bytesRead += responseSize;
+        if (responseSize < 8192) {
+            /* Nothing more to read */
             break;
         }
+        /* TODO Emit progress */
     } while (bytesRead < maxSize);
 
     return outputFile.commit();
--- a/ui/downloader.h	Mon Mar 17 14:47:18 2014 +0000
+++ b/ui/downloader.h	Mon Mar 17 14:48:05 2014 +0000
@@ -99,6 +99,17 @@
      */
     bool downloadFile(const QString &resource, const QString &filename,
                       size_t maxSize);
+    /**
+     * @brief parses the Headers of a repsonse.
+     *
+     * This removes the headers from the byte array passed as
+     * parameter.
+     *
+     * @param[inout] data: The response to parse.
+     *
+     * @returns: A map of the header fields. Or an empty map on error.
+     */
+    QMap<QString, QString> parseHeaders(QByteArray *data);
 
 Q_SIGNALS:
     /**

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