Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/desktop.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKlaas Freitag <freitag@owncloud.com>2015-05-15 16:34:17 +0300
committerKlaas Freitag <freitag@owncloud.com>2015-05-19 18:09:40 +0300
commit830daa40d1dae9064975e20c9295660fb8337fce (patch)
treedcc143937808d8c6a812c2e2bb7b09850c434aa1 /src
parentf016d25b4cc934fd539665a8beb86f301afd2b9a (diff)
Add a class TransmissionChecksumValidator, incl. unit test.
This does all needed to manage checksums that go with http headers ensuring that the transmission was correct.
Diffstat (limited to 'src')
-rw-r--r--src/libsync/CMakeLists.txt1
-rw-r--r--src/libsync/transmissionchecksumvalidator.cpp152
-rw-r--r--src/libsync/transmissionchecksumvalidator.h54
3 files changed, 207 insertions, 0 deletions
diff --git a/src/libsync/CMakeLists.txt b/src/libsync/CMakeLists.txt
index aaa1d93ca..7247d16a6 100644
--- a/src/libsync/CMakeLists.txt
+++ b/src/libsync/CMakeLists.txt
@@ -61,6 +61,7 @@ set(libsync_SRCS
theme.cpp
utility.cpp
ownsql.cpp
+ transmissionchecksumvalidator.cpp
creds/dummycredentials.cpp
creds/abstractcredentials.cpp
creds/credentialsfactory.cpp
diff --git a/src/libsync/transmissionchecksumvalidator.cpp b/src/libsync/transmissionchecksumvalidator.cpp
new file mode 100644
index 000000000..e6fd6f338
--- /dev/null
+++ b/src/libsync/transmissionchecksumvalidator.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) by Klaas Freitag <freitag@owncloud.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+#include "config.h"
+#include "filesystem.h"
+#include "transmissionchecksumvalidator.h"
+#include "syncfileitem.h"
+#include "propagatorjobs.h"
+#include "configfile.h"
+
+#include <QtConcurrent>
+
+namespace OCC {
+
+TransmissionChecksumValidator::TransmissionChecksumValidator(const QString& filePath, QObject *parent)
+ :QObject(parent),
+ _filePath(filePath)
+{
+
+}
+
+void TransmissionChecksumValidator::setChecksumType( const QByteArray& type )
+{
+ _checksumType = type;
+}
+
+QString TransmissionChecksumValidator::checksumType()
+{
+ return _checksumType;
+}
+
+
+void TransmissionChecksumValidator::uploadValidation( SyncFileItem *item )
+{
+ QString checksumType = _checksumType;
+ if( checksumType.isEmpty() ) {
+ ConfigFile cfg;
+ checksumType = cfg.transmissionChecksum();
+ }
+
+ if( checksumType.isEmpty() || !item ) {
+ // if there is no checksum defined, continue to upload
+ emit validated();
+ } else {
+ _item = item;
+ // Calculate the checksum in a different thread first.
+ connect( &_watcher, SIGNAL(finished()),
+ this, SLOT(slotUploadChecksumCalculated()));
+ if( checksumType == checkSumMD5C ) {
+ item->_checksum = checkSumMD5C;
+ item->_checksum += ":";
+ _watcher.setFuture(QtConcurrent::run(FileSystem::calcMd5Worker, _filePath));
+
+ } else if( checksumType == checkSumSHA1C ) {
+ item->_checksum = checkSumSHA1C;
+ item->_checksum += ":";
+ _watcher.setFuture(QtConcurrent::run( FileSystem::calcSha1Worker, _filePath));
+ }
+#ifdef ZLIB_FOUND
+ else if( checksumType == checkSumAdlerC) {
+ item->_checksum = checkSumAdlerC;
+ item->_checksum += ":";
+ _watcher.setFuture(QtConcurrent::run(FileSystem::calcAdler32Worker, _filePath));
+ }
+#endif
+ else {
+ // for an unknown checksum, continue to upload
+ emit validated();
+ }
+ }
+}
+
+void TransmissionChecksumValidator::slotUploadChecksumCalculated( )
+{
+ QByteArray checksum = _watcher.future().result();
+
+ if( !checksum.isEmpty() ) {
+ _item->_checksum.append(checksum);
+ } else {
+ _item->_checksum.clear();
+ }
+
+ emit validated();
+}
+
+
+void TransmissionChecksumValidator::downloadValidation( const QByteArray& checksumHeader )
+{
+ // if the incoming header is empty, there was no checksum header, and
+ // no validation can happen. Just continue.
+ if( checksumHeader.isEmpty() ) {
+ emit validated();
+ return;
+ }
+
+ bool ok = true;
+
+ int indx = checksumHeader.indexOf(':');
+ if( indx < 0 ) {
+ qDebug() << "Checksum header malformed:" << checksumHeader;
+ emit validated(); // show must go on - even not validated.
+ }
+
+ if( ok ) {
+ const QByteArray type = checksumHeader.left(indx).toUpper();
+ _expectedHash = checksumHeader.mid(indx+1);
+
+ connect( &_watcher, SIGNAL(finished()), this, SLOT(slotDownloadChecksumCalculated()) );
+
+ // start the calculation in different thread
+ if( type == checkSumMD5C ) {
+ _watcher.setFuture(QtConcurrent::run(FileSystem::calcMd5Worker, _filePath));
+ } else if( type == checkSumSHA1C ) {
+ _watcher.setFuture(QtConcurrent::run(FileSystem::calcSha1Worker, _filePath));
+ }
+#ifdef ZLIB_FOUND
+ else if( type == checkSumAdlerUpperC ) {
+ _watcher.setFuture(QtConcurrent::run(FileSystem::calcAdler32Worker, _filePath));
+ }
+#endif
+ else {
+ qDebug() << "Unknown checksum type" << type;
+ emit validationFailed(tr("The checksum header was malformed."));
+ return;
+ }
+ }
+}
+
+void TransmissionChecksumValidator::slotDownloadChecksumCalculated()
+{
+ const QByteArray hash = _watcher.future().result();
+
+ if( hash != _expectedHash ) {
+ emit validationFailed(tr("The file downloaded with a broken checksum, will be redownloaded."));
+ } else {
+ qDebug() << "Checksum checked and matching: " << _expectedHash;
+ emit validated();
+ }
+}
+
+
+}
diff --git a/src/libsync/transmissionchecksumvalidator.h b/src/libsync/transmissionchecksumvalidator.h
new file mode 100644
index 000000000..dc9f7effc
--- /dev/null
+++ b/src/libsync/transmissionchecksumvalidator.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) by Klaas Freitag <freitag@owncloud.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#pragma once
+
+#include <QObject>
+#include <QByteArray>
+#include <QFutureWatcher>
+
+namespace OCC {
+class SyncFileItem;
+
+class TransmissionChecksumValidator : public QObject
+{
+ Q_OBJECT
+public:
+ explicit TransmissionChecksumValidator(const QString& filePath, QObject *parent = 0);
+
+ void uploadValidation( SyncFileItem *item );
+ void downloadValidation( const QByteArray& checksumHeader );
+
+ void setChecksumType(const QByteArray &type );
+ QString checksumType();
+
+signals:
+ void validated();
+ void validationFailed( const QString& errMsg );
+
+private slots:
+ void slotUploadChecksumCalculated();
+ void slotDownloadChecksumCalculated();
+
+private:
+ QByteArray _checksumType;
+ QByteArray _expectedHash;
+ QString _filePath;
+ SyncFileItem *_item;
+
+ // watcher for the checksum calculation thread
+ QFutureWatcher<QByteArray> _watcher;
+};
+
+}