Merge pull request #4532 from ckamm/content-checksum

Enable content checksums #4375
This commit is contained in:
ckamm 2016-03-14 09:49:31 +01:00
commit 25baa995ec
5 changed files with 53 additions and 19 deletions

View file

@ -114,6 +114,15 @@ bool downloadChecksumEnabled()
return enabled;
}
QByteArray contentChecksumType()
{
static QByteArray type = qgetenv("OWNCLOUD_CONTENT_CHECKSUM_TYPE");
if (!type.isNull()) { // can set to "" to disable checksumming
return type;
}
return "SHA1";
}
ComputeChecksum::ComputeChecksum(QObject* parent)
: QObject(parent)
{

View file

@ -37,6 +37,10 @@ bool uploadChecksumEnabled();
/// Checks OWNCLOUD_DISABLE_CHECKSUM_DOWNLOAD
bool downloadChecksumEnabled();
/// Checks OWNCLOUD_CONTENT_CHECKSUM_TYPE (default: SHA1)
QByteArray contentChecksumType();
/**
* Computes the checksum of a file.
* \ingroup libsync

View file

@ -547,11 +547,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);
@ -649,13 +649,38 @@ static void preserveGroupOwnership(const QString& fileName, const QFileInfo& fi)
}
} // end namespace
void PropagateDownloadFileQNAM::downloadFinished(const QByteArray& transportChecksumType,
const QByteArray& transportChecksum)
{
// by default, reuse the transport checksum as content checksum
_item->_contentChecksum = transportChecksum;
_item->_contentChecksumType = transportChecksumType;
void PropagateDownloadFileQNAM::transmissionChecksumValidated(const QByteArray &checksumType, const QByteArray &checksum)
{
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

View file

@ -131,8 +131,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 );

View file

@ -219,23 +219,18 @@ void PropagateUploadFileQNAM::slotComputeContentChecksum()
_stopWatch.start();
QByteArray contentChecksumType;
// We currently only do content checksums for the particular .eml case
// This should be done more generally in the future!
if (filePath.endsWith(QLatin1String(".eml"), Qt::CaseInsensitive)) {
contentChecksumType = "MD5";
}
QByteArray checksumType = contentChecksumType();
// Maybe the discovery already computed the checksum?
if (_item->_contentChecksumType == contentChecksumType
if (_item->_contentChecksumType == checksumType
&& !_item->_contentChecksum.isEmpty()) {
slotComputeTransmissionChecksum(contentChecksumType, _item->_contentChecksum);
slotComputeTransmissionChecksum(checksumType, _item->_contentChecksum);
return;
}
// Compute the content checksum.
auto computeChecksum = new ComputeChecksum(this);
computeChecksum->setChecksumType(contentChecksumType);
computeChecksum->setChecksumType(checksumType);
connect(computeChecksum, SIGNAL(done(QByteArray,QByteArray)),
SLOT(slotComputeTransmissionChecksum(QByteArray,QByteArray)));