From c7f759fedf2b176d229e4008faae9c134b137269 Mon Sep 17 00:00:00 2001 From: Klaas Freitag Date: Fri, 15 May 2015 15:39:26 +0200 Subject: [PATCH] Propagator: Use the TransmissionChecksumValidator class. --- src/libsync/propagatedownload.cpp | 75 +++++++------------------------ src/libsync/propagatedownload.h | 15 +++---- src/libsync/propagateupload.cpp | 69 +++++++--------------------- src/libsync/propagateupload.h | 12 ++--- 4 files changed, 46 insertions(+), 125 deletions(-) diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp index 8975b4156..fc943d0fc 100644 --- a/src/libsync/propagatedownload.cpp +++ b/src/libsync/propagatedownload.cpp @@ -22,13 +22,14 @@ #include "utility.h" #include "filesystem.h" #include "propagatorjobs.h" +#include "transmissionchecksumvalidator.h" + #include #include #include #include #include #include -#include namespace OCC { @@ -485,68 +486,22 @@ 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(); - } + // do whatever is needed to add a checksum to the http upload request. + // in any case, the validator will emit signal startUpload to let the flow + // continue in slotStartUpload here. + _validator = new TransmissionChecksumValidator( _tmpFile.fileName() ); + connect(_validator, SIGNAL(validated()), this, SLOT(downloadFinished())); + connect(_validator, SIGNAL(validationFailed(QString)), this, SLOT(slotChecksumFail(QString))); + _validator->downloadValidation(job->reply()->rawHeader(checkSumHeaderC)); } -void PropagateDownloadFileQNAM::slotDownloadChecksumCheckFinished() +void PropagateDownloadFileQNAM::slotChecksumFail( const QString& errMsg ) { - 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(); + _validator->deleteLater(); + _tmpFile.remove(); + _propagator->_anotherSyncNeeded = true; + done(SyncFileItem::SoftError, errMsg ); // tr("The file downloaded with a broken checksum, will be redownloaded.")); } QString makeConflictFileName(const QString &fn, const QDateTime &dt) @@ -572,6 +527,8 @@ QString makeConflictFileName(const QString &fn, const QDateTime &dt) void PropagateDownloadFileQNAM::downloadFinished() { + _validator->deleteLater(); + QString fn = _propagator->getFilePath(_item._file); // In case of file name clash, report an error diff --git a/src/libsync/propagatedownload.h b/src/libsync/propagatedownload.h index 65ef9aff3..7ec9bd3db 100644 --- a/src/libsync/propagatedownload.h +++ b/src/libsync/propagatedownload.h @@ -18,10 +18,11 @@ #include #include -#include namespace OCC { +class TransmissionChecksumValidator; + class GETFileJob : public AbstractNetworkJob { Q_OBJECT QFile* _device; @@ -102,9 +103,6 @@ private slots: class PropagateDownloadFileQNAM : public PropagateItemJob { Q_OBJECT - QPointer _job; - - QFile _tmpFile; public: PropagateDownloadFileQNAM(OwncloudPropagator* propagator,const SyncFileItem& item) : PropagateItemJob(propagator, item) {} @@ -115,12 +113,13 @@ private slots: void abort() Q_DECL_OVERRIDE; void downloadFinished(); void slotDownloadProgress(qint64,qint64); - void slotDownloadChecksumCheckFinished(); + void slotChecksumFail( const QString& errMsg ); private: - QByteArray _expectedHash; - QFutureWatcher _watcher; - Utility::StopWatch _stopWatch; + // Utility::StopWatch _stopWatch; + QPointer _job; + QFile _tmpFile; + TransmissionChecksumValidator *_validator; }; diff --git a/src/libsync/propagateupload.cpp b/src/libsync/propagateupload.cpp index 0ebde657a..cfd34d034 100644 --- a/src/libsync/propagateupload.cpp +++ b/src/libsync/propagateupload.cpp @@ -22,6 +22,7 @@ #include "utility.h" #include "filesystem.h" #include "propagatorjobs.h" +#include "transmissionchecksumvalidator.h" #include "configfile.h" #include @@ -30,7 +31,6 @@ #include #include #include -#include #ifdef USE_NEON #include "propagator_legacy.h" @@ -194,72 +194,32 @@ bool PollJob::finished() return true; } - void PropagateUploadFileQNAM::start() { if (_propagator->_abortRequested.fetchAndAddRelaxed(0)) { return; } - ConfigFile cfg; // FIXME: Do not open it for each and every propagation. const QString filePath = _propagator->getFilePath(_item._file); + + // remember the modtime before checksumming to be able to detect a file + // change during the checksum calculation _item._modtime = FileSystem::getModTime(filePath); - // calculate the files checksum - const QString transChecksum = cfg.transmissionChecksum(); _stopWatch.start(); - if( transChecksum.isEmpty() ) { - // no checksumming required, jump to really start the uplaod - startUpload(); - } else { - // Calculate the checksum in a different thread first. - connect( &_watcher, SIGNAL(finished()), - this, SLOT(slotChecksumCalculated())); - bool haveFuture = true; - if( transChecksum == checkSumMD5C ) { - _item._checksum = checkSumMD5C; - _item._checksum += ":"; - _watcher.setFuture(QtConcurrent::run(FileSystem::calcMd5Worker,filePath)); - - } else if( transChecksum == checkSumSHA1C ) { - _item._checksum = checkSumSHA1C; - _item._checksum += ":"; - _watcher.setFuture(QtConcurrent::run( FileSystem::calcSha1Worker, filePath)); - } -#ifdef ZLIB_FOUND - else if( transChecksum == checkSumAdlerC) { - _item._checksum = checkSumAdlerC; - _item._checksum += ":"; - _watcher.setFuture(QtConcurrent::run(FileSystem::calcAdler32Worker, filePath)); - } -#endif - else { - haveFuture = false; - } - // in case there is a wrong checksum header, let continue without - if( !haveFuture ) { - startUpload(); - } - } - + // do whatever is needed to add a checksum to the http upload request. + // in any case, the validator will emit signal startUpload to let the flow + // continue in slotStartUpload here. + _validator = new TransmissionChecksumValidator(filePath); + connect(_validator, SIGNAL(validated()), this, SLOT(slotStartUpload())); + _validator->uploadValidation( &_item ); } -void PropagateUploadFileQNAM::slotChecksumCalculated( ) +void PropagateUploadFileQNAM::slotStartUpload() { - QByteArray checksum = _watcher.future().result(); + _validator->deleteLater(); - if( !checksum.isEmpty() ) { - _item._checksum.append(checksum); - } else { - _item._checksum.clear(); - } - - startUpload(); -} - -void PropagateUploadFileQNAM::startUpload() -{ const QString fullFilePath(_propagator->getFilePath(_item._file)); if (!FileSystem::fileExists(fullFilePath)) { @@ -499,6 +459,11 @@ void PropagateUploadFileQNAM::startNextChunk() headers[checkSumHeaderC] = _item._checksum; } } + } else { + // checksum if its only one chunk + if( !_item._checksum.isEmpty() ) { + headers[checkSumHeaderC] = _item._checksum; + } } if (! device->prepareAndOpen(_propagator->getFilePath(_item._file), chunkStart, currentChunkSize)) { diff --git a/src/libsync/propagateupload.h b/src/libsync/propagateupload.h index 1e3b6f2e1..7b5e11fd1 100644 --- a/src/libsync/propagateupload.h +++ b/src/libsync/propagateupload.h @@ -19,11 +19,11 @@ #include #include #include -#include namespace OCC { class BandwidthManager; +class TransmissionChecksumValidator; class UploadDevice : public QIODevice { Q_OBJECT @@ -169,11 +169,11 @@ private: QVector _jobs; /// network jobs that are currently in transit bool _finished; // Tells that all the jobs have been finished - // watcher for the checksum calculation thread - QFutureWatcher _watcher; - // measure the performance of checksum calc and upload Utility::StopWatch _stopWatch; + + TransmissionChecksumValidator *_validator; + public: PropagateUploadFileQNAM(OwncloudPropagator* propagator,const SyncFileItem& item) : PropagateItemJob(propagator, item), _startChunk(0), _currentChunk(0), _chunkCount(0), _transferId(0), _finished(false) {} @@ -186,8 +186,8 @@ private slots: void startNextChunk(); void finalize(const SyncFileItem&); void slotJobDestroyed(QObject *job); - void startUpload(); - void slotChecksumCalculated(); + void slotStartUpload(); + private: void startPollJob(const QString& path); void abortWithError(SyncFileItem::Status status, const QString &error); -- 2.30.2