|
@@ -25,6 +25,8 @@
|
|
#include "ctkXnatObjectPrivate.h"
|
|
#include "ctkXnatObjectPrivate.h"
|
|
#include "ctkXnatSession.h"
|
|
#include "ctkXnatSession.h"
|
|
|
|
|
|
|
|
+#include <QCryptographicHash>
|
|
|
|
+#include <QDebug>
|
|
#include <QFile>
|
|
#include <QFile>
|
|
|
|
|
|
const QString ctkXnatFile::FILE_NAME = "Name";
|
|
const QString ctkXnatFile::FILE_NAME = "Name";
|
|
@@ -138,6 +140,7 @@ void ctkXnatFile::reset()
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
void ctkXnatFile::fetchImpl()
|
|
void ctkXnatFile::fetchImpl()
|
|
{
|
|
{
|
|
|
|
+ // Does not make sense to fetch a file
|
|
}
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
@@ -150,6 +153,7 @@ void ctkXnatFile::downloadImpl(const QString& filename)
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
void ctkXnatFile::saveImpl()
|
|
void ctkXnatFile::saveImpl()
|
|
{
|
|
{
|
|
|
|
+ Q_D(ctkXnatFile);
|
|
QString query = this->resourceUri();
|
|
QString query = this->resourceUri();
|
|
QString filename = this->localFilePath();
|
|
QString filename = this->localFilePath();
|
|
|
|
|
|
@@ -182,24 +186,58 @@ void ctkXnatFile::saveImpl()
|
|
query.append(QString("&%1=%2").arg("content", this->fileContent()));
|
|
query.append(QString("&%1=%2").arg("content", this->fileContent()));
|
|
query.append(QString("&%1=%2").arg("tags", this->fileTags()));
|
|
query.append(QString("&%1=%2").arg("tags", this->fileTags()));
|
|
|
|
|
|
|
|
+ // TODO May be flag for setting overwrite and not doing this automatically
|
|
if (this->exists())
|
|
if (this->exists())
|
|
query.append(QString("&%1=%2").arg("overwrite", true));
|
|
query.append(QString("&%1=%2").arg("overwrite", true));
|
|
|
|
|
|
|
|
+ // Flag needed for file upload
|
|
query.append(QString("&%1=%2").arg("inbody", "true"));
|
|
query.append(QString("&%1=%2").arg("inbody", "true"));
|
|
|
|
|
|
this->session()->upload(filename, query);
|
|
this->session()->upload(filename, query);
|
|
- qint64 localFileSize = file.size();
|
|
|
|
- QUuid queryId = this->session()->httpHead(this->resourceUri());
|
|
|
|
- QMap<QByteArray, QByteArray> header = this->session()->httpHeadSync(queryId);
|
|
|
|
- QVariant sizeOnServer = header.value("Content-Length");
|
|
|
|
- qint64 remoteFileSize = sizeOnServer.toLongLong();
|
|
|
|
-
|
|
|
|
- // Retrieving the md5 checksum on the server is not always possible
|
|
|
|
- // At least we can check whether the file size is the same
|
|
|
|
- if (remoteFileSize != localFileSize)
|
|
|
|
|
|
+
|
|
|
|
+ // Validating the file upload by requesting the catalog XML
|
|
|
|
+ // of the parent resource. Unfortunately for XNAT versions <= 1.6.4
|
|
|
|
+ // this is the only way to get the file's MD5 hash form the server.
|
|
|
|
+ QString md5Query = this->parent()->resourceUri();
|
|
|
|
+ QUuid md5ID = this->session()->httpGet(md5Query);
|
|
|
|
+ QList<QVariantMap> result = this->session()->httpSync(md5ID);
|
|
|
|
+
|
|
|
|
+ QString md5ChecksumRemote ("0");
|
|
|
|
+ // Newly added files are usually at the end of the catalog
|
|
|
|
+ // and hence at the end of the result list. So iterating backwards
|
|
|
|
+ // is for performance reasons.
|
|
|
|
+ QList<QVariantMap>::const_iterator it = result.constEnd()-1;
|
|
|
|
+ while (it != result.constBegin())
|
|
|
|
+ {
|
|
|
|
+ QVariantMap::const_iterator it2 = (*it).find(this->name());
|
|
|
|
+ if (it2 != (*it).constEnd())
|
|
|
|
+ {
|
|
|
|
+ md5ChecksumRemote = it2.value().toString();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ --it;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (file.open(QFile::ReadOnly) && md5ChecksumRemote != "0")
|
|
|
|
+ {
|
|
|
|
+ QCryptographicHash hash(QCryptographicHash::Md5);
|
|
|
|
+ // TODO Do this in case of Qt5
|
|
|
|
+ //if (hash.addData(&file))
|
|
|
|
+ hash.addData(file.readAll());
|
|
|
|
+ QString md5ChecksumLocal(hash.result().toHex());
|
|
|
|
+ // Retrieving the md5 checksum on the server and comparing
|
|
|
|
+ // if with the local file md5 sum
|
|
|
|
+ if (md5ChecksumLocal != md5ChecksumRemote)
|
|
|
|
+ {
|
|
|
|
+ // Remove corrupted file from server
|
|
|
|
+ this->erase();
|
|
|
|
+ throw ctkXnatException("Upload failed! An error occurred during file upload.");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
{
|
|
{
|
|
- // Remove corrupted file from server
|
|
|
|
- this->erase();
|
|
|
|
- throw ctkXnatException("Upload failed! An error occurred during file upload.");
|
|
|
|
|
|
+ qWarning()<<"Could not validate file upload!";
|
|
}
|
|
}
|
|
|
|
+ // End file validation
|
|
|
|
+
|
|
}
|
|
}
|