Checksums: Compute content checksum on download #4375
authorChristian Kamm <mail@ckamm.de>
Wed, 2 Mar 2016 13:20:36 +0000 (14:20 +0100)
committerChristian Kamm <mail@ckamm.de>
Wed, 2 Mar 2016 13:28:41 +0000 (14:28 +0100)
src/libsync/propagatedownload.cpp
src/libsync/propagatedownload.h

index 60a0183a6f7d11a9d11337fa9576771ec10f8c18..fd3b6a78bb5b9dc183618eb9875a53d6a233823f 100644 (file)
@@ -546,11 +546,11 @@ void PropagateDownloadFileQNAM::slotGetFinished()
     }
 
     // Do checksum validation for the download. If there is no checksum header, the validator
-    // will also emit the validated() signal to continue the flow in slot downloadFinished()
+    // will also emit the validated() signal to continue the flow in slot transmissionChecksumValidated()
     // as this is (still) also correct.
     ValidateChecksumHeader *validator = new ValidateChecksumHeader(this);
     connect(validator, SIGNAL(validated(QByteArray,QByteArray)),
-            SLOT(downloadFinished(QByteArray,QByteArray)));
+            SLOT(transmissionChecksumValidated(QByteArray,QByteArray)));
     connect(validator, SIGNAL(validationFailed(QString)),
             SLOT(slotChecksumFail(QString)));
     auto checksumHeader = job->reply()->rawHeader(checkSumHeaderC);
@@ -638,13 +638,38 @@ static void handleRecallFile(const QString &fn)
 }
 } // end namespace
 
-void PropagateDownloadFileQNAM::downloadFinished(const QByteArray& transportChecksumType,
-                                                 const QByteArray& transportChecksum)
+
+void PropagateDownloadFileQNAM::transmissionChecksumValidated(const QByteArray &checksumType, const QByteArray &checksum)
 {
-    // by default, reuse the transport checksum as content checksum
-    _item->_contentChecksum = transportChecksum;
-    _item->_contentChecksumType = transportChecksumType;
+    const auto theContentChecksumType = contentChecksumType();
+
+    // Reuse transmission checksum as content checksum.
+    //
+    // We could do this more aggressively and accept both MD5 and SHA1
+    // instead of insisting on the exactly correct checksum type.
+    if (theContentChecksumType == checksumType || theContentChecksumType.isEmpty()) {
+        return contentChecksumComputed(checksumType, checksum);
+    }
+
+    // Compute the content checksum.
+    auto computeChecksum = new ComputeChecksum(this);
+    computeChecksum->setChecksumType(theContentChecksumType);
+
+    connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
+            SLOT(contentChecksumComputed(QByteArray,QByteArray)));
+    computeChecksum->start(_tmpFile.fileName());
+}
 
+void PropagateDownloadFileQNAM::contentChecksumComputed(const QByteArray &checksumType, const QByteArray &checksum)
+{
+    _item->_contentChecksum = checksum;
+    _item->_contentChecksumType = checksumType;
+
+    downloadFinished();
+}
+
+void PropagateDownloadFileQNAM::downloadFinished()
+{
     QString fn = _propagator->getFilePath(_item->_file);
 
     // In case of file name clash, report an error
index ba70d2a999fc060901105231d89bd8dc6f3c0ae8..32829fa8f8bef1b2376e2800134ba7e85e14384c 100644 (file)
@@ -128,8 +128,9 @@ public:
 private slots:
     void slotGetFinished();
     void abort() Q_DECL_OVERRIDE;
-    void downloadFinished(const QByteArray& transportChecksumType = QByteArray(),
-                          const QByteArray &transportChecksum = QByteArray());
+    void transmissionChecksumValidated(const QByteArray& checksumType, const QByteArray& checksum);
+    void contentChecksumComputed(const QByteArray& checksumType, const QByteArray& checksum);
+    void downloadFinished();
     void slotDownloadProgress(qint64,qint64);
     void slotChecksumFail( const QString& errMsg );