From f016d25b4cc934fd539665a8beb86f301afd2b9a Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Fri, 15 May 2015 10:50:55 +0200 Subject: [PATCH] Propagate downloads: Handle checksum transmission header. Read a checksum from the HTTP header, and if its there, compare the downloaded tmp file against it. In case of corruption, schedule a redownload. --- src/libsync/propagatedownload.cpp | 64 ++++++++++++++++++++++++++++++- src/libsync/propagatedownload.h | 10 ++++- src/libsync/propagateupload.cpp | 1 + 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index 65fc409a7..8975b4156 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -12,6 +12,7 @@ * for more details. */ +#include "config.h" #include "owncloudpropagator_p.h" #include "propagatedownload.h" #include "networkjobs.h" @@ -27,10 +28,10 @@ #include #include #include +#include namespace OCC { - // Always coming in with forward slashes. // In csync_excluded_no_ctx we ignore all files with longer than 254 chars // This function also adds a dot at the begining of the filename to hide the file on OS X and Linux @@ -484,6 +485,67 @@ void PropagateDownloadFileQNAM::slotGetFinished() return; } + /* Check if a checksum was transmitted */ + if( job->reply()->hasRawHeader(checkSumHeaderC)) { + QByteArray header = job->reply()->rawHeader(checkSumHeaderC); + + bool ok = true; + + int indx = header.indexOf(':'); + if( indx < 0 ) { + qDebug() << "Checksum header malformed:" << header; + ok = false; + } + + if( ok ) { + const QByteArray type = header.left(indx).toUpper(); + _expectedHash = header.mid(indx+1); + + connect( &_watcher, SIGNAL(finished()), this, SLOT(slotDownloadChecksumCheckFinished())); + + // start the calculation in different thread + if( type == checkSumMD5C ) { + _watcher.setFuture(QtConcurrent::run(FileSystem::calcMd5Worker, _tmpFile.fileName())); + } else if( type == checkSumSHA1C ) { + _watcher.setFuture(QtConcurrent::run(FileSystem::calcSha1Worker, _tmpFile.fileName())); + } +#ifdef ZLIB_FOUND + else if( type == checkSumAdlerUpperC ) { + _watcher.setFuture(QtConcurrent::run(FileSystem::calcAdler32Worker, _tmpFile.fileName())); + } +#endif + else { + qDebug() << "Unknown checksum type" << type; + ok = false; + } + } + + if( !ok) { + _tmpFile.remove(); + _propagator->_anotherSyncNeeded = true; + done(SyncFileItem::SoftError, tr("The checksum header was malformed.")); + return; + } + } else { + // No OC-Checksum header, go directly to continue handle the download + downloadFinished(); + } + +} + +void PropagateDownloadFileQNAM::slotDownloadChecksumCheckFinished() +{ + const QByteArray hash = _watcher.future().result(); + + if( hash != _expectedHash ) { + _tmpFile.remove(); + _propagator->_anotherSyncNeeded = true; + done(SyncFileItem::SoftError, tr("The file downloaded with a broken checksum, will be redownloaded.")); + return; + } else { + qDebug() << "Checksum checked and matching: " << _expectedHash; + } + downloadFinished(); } diff --git a/src/libsync/propagatedownload.h b/src/libsync/propagatedownload.h index 47c60702a..65ef9aff3 100644 --- a/src/libsync/propagatedownload.h +++ b/src/libsync/propagatedownload.h @@ -18,6 +18,7 @@ #include #include +#include namespace OCC { @@ -103,17 +104,24 @@ class PropagateDownloadFileQNAM : public PropagateItemJob { Q_OBJECT QPointer _job; -// QFile *_file; QFile _tmpFile; public: PropagateDownloadFileQNAM(OwncloudPropagator* propagator,const SyncFileItem& item) : PropagateItemJob(propagator, item) {} void start() Q_DECL_OVERRIDE; + private slots: void slotGetFinished(); void abort() Q_DECL_OVERRIDE; void downloadFinished(); void slotDownloadProgress(qint64,qint64); + void slotDownloadChecksumCheckFinished(); + +private: + QByteArray _expectedHash; + QFutureWatcher _watcher; + Utility::StopWatch _stopWatch; + }; } diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index bdd6a4860..0ebde657a 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -12,6 +12,7 @@ * for more details. */ +#include "config.h" #include "propagateupload.h" #include "owncloudpropagator_p.h" #include "networkjobs.h" -- 2.30.2