Use byte array for etag

This commit is contained in:
Hannah von Reth 2021-02-25 14:42:23 +01:00 committed by Matthieu Gallien
parent 5a7fd3f316
commit 5b457a1663
11 changed files with 40 additions and 35 deletions

View file

@ -104,6 +104,7 @@ public:
ASSERT(!_isError); ASSERT(!_isError);
return _result; return _result;
} }
T operator*() && T operator*() &&
{ {
ASSERT(!_isError); ASSERT(!_isError);
@ -116,6 +117,12 @@ public:
return &_result; return &_result;
} }
const T &get() const
{
ASSERT(!_isError)
return _result;
}
const Error &error() const & const Error &error() const &
{ {
ASSERT(_isError); ASSERT(_isError);

View file

@ -353,7 +353,7 @@ void Folder::slotRunEtagJob()
// The _requestEtagJob is auto deleting itself on finish. Our guard pointer _requestEtagJob will then be null. // The _requestEtagJob is auto deleting itself on finish. Our guard pointer _requestEtagJob will then be null.
} }
void Folder::etagRetrieved(const QString &etag, const QDateTime &tp) void Folder::etagRetrieved(const QByteArray &etag, const QDateTime &tp)
{ {
// re-enable sync if it was disabled because network was down // re-enable sync if it was disabled because network was down
FolderMan::instance()->setSyncEnabled(true); FolderMan::instance()->setSyncEnabled(true);
@ -367,7 +367,7 @@ void Folder::etagRetrieved(const QString &etag, const QDateTime &tp)
_accountState->tagLastSuccessfullETagRequest(tp); _accountState->tagLastSuccessfullETagRequest(tp);
} }
void Folder::etagRetrievedFromSyncEngine(const QString &etag, const QDateTime &time) void Folder::etagRetrievedFromSyncEngine(const QByteArray &etag, const QDateTime &time)
{ {
qCInfo(lcFolder) << "Root etag from during sync:" << etag; qCInfo(lcFolder) << "Root etag from during sync:" << etag;
accountState()->tagLastSuccessfullETagRequest(time); accountState()->tagLastSuccessfullETagRequest(time);

View file

@ -376,8 +376,8 @@ private slots:
void slotItemCompleted(const SyncFileItemPtr &); void slotItemCompleted(const SyncFileItemPtr &);
void slotRunEtagJob(); void slotRunEtagJob();
void etagRetrieved(const QString &, const QDateTime &tp); void etagRetrieved(const QByteArray &, const QDateTime &tp);
void etagRetrievedFromSyncEngine(const QString &, const QDateTime &time); void etagRetrievedFromSyncEngine(const QByteArray &, const QDateTime &time);
void slotEmitFinishedDelayed(); void slotEmitFinishedDelayed();
@ -447,7 +447,7 @@ private:
SyncResult _syncResult; SyncResult _syncResult;
QScopedPointer<SyncEngine> _engine; QScopedPointer<SyncEngine> _engine;
QPointer<RequestEtagJob> _requestEtagJob; QPointer<RequestEtagJob> _requestEtagJob;
QString _lastEtag; QByteArray _lastEtag;
QElapsedTimer _timeSinceLastSyncDone; QElapsedTimer _timeSinceLastSyncDone;
QElapsedTimer _timeSinceLastSyncStart; QElapsedTimer _timeSinceLastSyncStart;
QElapsedTimer _timeSinceLastFullLocalDiscovery; QElapsedTimer _timeSinceLastFullLocalDiscovery;

View file

@ -528,7 +528,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
} }
return ParentNotChanged; return ParentNotChanged;
}(); }();
processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, serverQueryMode); processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, serverQueryMode);
return; return;
} }
@ -545,15 +545,14 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
item->_modtime = serverEntry.modtime; item->_modtime = serverEntry.modtime;
item->_size = serverEntry.size; item->_size = serverEntry.size;
auto postProcessServerNew = [=] () { auto postProcessServerNew = [=]() mutable {
auto tmp_path = path;
if (item->isDirectory()) { if (item->isDirectory()) {
_pendingAsyncJobs++; _pendingAsyncJobs++;
_discoveryData->checkSelectiveSyncNewFolder(tmp_path._server, serverEntry.remotePerm, _discoveryData->checkSelectiveSyncNewFolder(path._server, serverEntry.remotePerm,
[=](bool result) { [=](bool result) {
--_pendingAsyncJobs; --_pendingAsyncJobs;
if (!result) { if (!result) {
processFileAnalyzeLocalInfo(item, tmp_path, localEntry, serverEntry, dbEntry, _queryServer); processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, _queryServer);
} }
QTimer::singleShot(0, _discoveryData, &DiscoveryPhase::scheduleMoreJobs); QTimer::singleShot(0, _discoveryData, &DiscoveryPhase::scheduleMoreJobs);
}); });
@ -568,7 +567,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
&& !FileSystem::isExcludeFile(item->_file)) { && !FileSystem::isExcludeFile(item->_file)) {
item->_type = ItemTypeVirtualFile; item->_type = ItemTypeVirtualFile;
if (isVfsWithSuffix()) if (isVfsWithSuffix())
addVirtualFileSuffix(tmp_path._original); addVirtualFileSuffix(path._original);
} }
if (opts._vfs->mode() != Vfs::Off && !item->_encryptedFileName.isEmpty()) { if (opts._vfs->mode() != Vfs::Off && !item->_encryptedFileName.isEmpty()) {
@ -579,7 +578,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
// another scenario - we are syncing a file which is on disk but not in the database (database was removed or file was not written there yet) // another scenario - we are syncing a file which is on disk but not in the database (database was removed or file was not written there yet)
item->_size = serverEntry.size - Constants::e2EeTagSize; item->_size = serverEntry.size - Constants::e2EeTagSize;
} }
processFileAnalyzeLocalInfo(item, tmp_path, localEntry, serverEntry, dbEntry, _queryServer); processFileAnalyzeLocalInfo(item, path, localEntry, serverEntry, dbEntry, _queryServer);
}; };
// Potential NEW/NEW conflict is handled in AnalyzeLocal // Potential NEW/NEW conflict is handled in AnalyzeLocal
@ -698,8 +697,7 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
// we need to make a request to the server to know that the original file is deleted on the server // we need to make a request to the server to know that the original file is deleted on the server
_pendingAsyncJobs++; _pendingAsyncJobs++;
auto job = new RequestEtagJob(_discoveryData->_account, originalPath, this); auto job = new RequestEtagJob(_discoveryData->_account, originalPath, this);
connect(job, &RequestEtagJob::finishedWithResult, this, [=](const HttpResult<QString> &etag) { connect(job, &RequestEtagJob::finishedWithResult, this, [=](const HttpResult<QByteArray> &etag) mutable {
auto tmp_path = path;
_pendingAsyncJobs--; _pendingAsyncJobs--;
QTimer::singleShot(0, _discoveryData, &DiscoveryPhase::scheduleMoreJobs); QTimer::singleShot(0, _discoveryData, &DiscoveryPhase::scheduleMoreJobs);
if (etag || etag.error().code != 404 || if (etag || etag.error().code != 404 ||
@ -715,8 +713,8 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(
// In case the deleted item was discovered in parallel // In case the deleted item was discovered in parallel
_discoveryData->findAndCancelDeletedJob(originalPath); _discoveryData->findAndCancelDeletedJob(originalPath);
postProcessRename(tmp_path); postProcessRename(path);
processFileFinalize(item, tmp_path, item->isDirectory(), item->_instruction == CSYNC_INSTRUCTION_RENAME ? NormalQuery : ParentDontExist, _queryServer); processFileFinalize(item, path, item->isDirectory(), item->_instruction == CSYNC_INSTRUCTION_RENAME ? NormalQuery : ParentDontExist, _queryServer);
}); });
job->start(); job->start();
done = true; // Ideally, if the origin still exist on the server, we should continue searching... but that'd be difficult done = true; // Ideally, if the origin still exist on the server, we should continue searching... but that'd be difficult
@ -1162,8 +1160,8 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
if (base.isVirtualFile() && isVfsWithSuffix()) if (base.isVirtualFile() && isVfsWithSuffix())
chopVirtualFileSuffix(serverOriginalPath); chopVirtualFileSuffix(serverOriginalPath);
auto job = new RequestEtagJob(_discoveryData->_account, serverOriginalPath, this); auto job = new RequestEtagJob(_discoveryData->_account, serverOriginalPath, this);
connect(job, &RequestEtagJob::finishedWithResult, this, [=](const HttpResult<QString> &etag) mutable { connect(job, &RequestEtagJob::finishedWithResult, this, [=](const HttpResult<QByteArray> &etag) mutable {
if (!etag || (*etag != base._etag && !item->isDirectory()) || _discoveryData->isRenamed(originalPath)) { if (!etag || (etag.get() != base._etag && !item->isDirectory()) || _discoveryData->isRenamed(originalPath)) {
qCInfo(lcDisco) << "Can't rename because the etag has changed or the directory is gone" << originalPath; qCInfo(lcDisco) << "Can't rename because the etag has changed or the directory is gone" << originalPath;
// Can't be a rename, leave it as a new. // Can't be a rename, leave it as a new.
postProcessLocalNew(); postProcessLocalNew();
@ -1171,7 +1169,7 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
// In case the deleted item was discovered in parallel // In case the deleted item was discovered in parallel
_discoveryData->findAndCancelDeletedJob(originalPath); _discoveryData->findAndCancelDeletedJob(originalPath);
processRename(path); processRename(path);
recurseQueryServer = *etag == base._etag ? ParentNotChanged : NormalQuery; recurseQueryServer = etag.get() == base._etag ? ParentNotChanged : NormalQuery;
} }
processFileFinalize(item, path, item->isDirectory(), NormalQuery, recurseQueryServer); processFileFinalize(item, path, item->isDirectory(), NormalQuery, recurseQueryServer);
_pendingAsyncJobs--; _pendingAsyncJobs--;

View file

@ -293,6 +293,6 @@ private:
signals: signals:
void finished(); void finished();
// The root etag of this directory was fetched // The root etag of this directory was fetched
void etag(const QString &, const QDateTime &time); void etag(const QByteArray &, const QDateTime &time);
}; };
} }

View file

@ -486,7 +486,7 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(const QString &fi
//This works in concerto with the RequestEtagJob and the Folder object to check if the remote folder changed. //This works in concerto with the RequestEtagJob and the Folder object to check if the remote folder changed.
if (map.contains("getetag")) { if (map.contains("getetag")) {
if (_firstEtag.isEmpty()) { if (_firstEtag.isEmpty()) {
_firstEtag = parseEtag(map.value("getetag").toUtf8()); // for directory itself _firstEtag = parseEtag(map.value(QStringLiteral("getetag")).toUtf8()); // for directory itself
} }
} }
} }

View file

@ -127,7 +127,7 @@ public:
// This is not actually a network job, it is just a job // This is not actually a network job, it is just a job
signals: signals:
void firstDirectoryPermissions(RemotePermissions); void firstDirectoryPermissions(RemotePermissions);
void etag(const QString &, const QDateTime &time); void etag(const QByteArray &, const QDateTime &time);
void finished(const HttpResult<QVector<RemoteInfo>> &result); void finished(const HttpResult<QVector<RemoteInfo>> &result);
private slots: private slots:
@ -141,7 +141,7 @@ private slots:
private: private:
QVector<RemoteInfo> _results; QVector<RemoteInfo> _results;
QString _subPath; QString _subPath;
QString _firstEtag; QByteArray _firstEtag;
QByteArray _fileId; QByteArray _fileId;
AccountPtr _account; AccountPtr _account;
// The first result is for the directory itself and need to be ignored. // The first result is for the directory itself and need to be ignored.

View file

@ -113,8 +113,8 @@ bool RequestEtagJob::finished()
if (httpCode == 207) { if (httpCode == 207) {
// Parse DAV response // Parse DAV response
QXmlStreamReader reader(reply()); QXmlStreamReader reader(reply());
reader.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration("d", "DAV:")); reader.addExtraNamespaceDeclaration(QXmlStreamNamespaceDeclaration(QStringLiteral("d"), QStringLiteral("DAV:")));
QString etag; QByteArray etag;
while (!reader.atEnd()) { while (!reader.atEnd()) {
QXmlStreamReader::TokenType type = reader.readNext(); QXmlStreamReader::TokenType type = reader.readNext();
if (type == QXmlStreamReader::StartElement && reader.namespaceUri() == QLatin1String("DAV:")) { if (type == QXmlStreamReader::StartElement && reader.namespaceUri() == QLatin1String("DAV:")) {
@ -123,9 +123,9 @@ bool RequestEtagJob::finished()
auto etagText = reader.readElementText(); auto etagText = reader.readElementText();
auto parsedTag = parseEtag(etagText.toUtf8()); auto parsedTag = parseEtag(etagText.toUtf8());
if (!parsedTag.isEmpty()) { if (!parsedTag.isEmpty()) {
etag += QString::fromUtf8(parsedTag); etag += parsedTag;
} else { } else {
etag += etagText; etag += etagText.toUtf8();
} }
} }
} }

View file

@ -349,8 +349,8 @@ public:
void start() override; void start() override;
signals: signals:
void etagRetrieved(const QString &etag, const QDateTime &time); void etagRetrieved(const QByteArray &etag, const QDateTime &time);
void finishedWithResult(const HttpResult<QString> &etag); void finishedWithResult(const HttpResult<QByteArray> &etag);
private slots: private slots:
bool finished() override; bool finished() override;
@ -421,10 +421,10 @@ signals:
* @param statusCode - the OCS status code: 100 (!) for success * @param statusCode - the OCS status code: 100 (!) for success
*/ */
void etagResponseHeaderReceived(const QByteArray &value, int statusCode); void etagResponseHeaderReceived(const QByteArray &value, int statusCode);
/** /**
* @brief desktopNotificationStatusReceived - signal to report if notifications are allowed * @brief desktopNotificationStatusReceived - signal to report if notifications are allowed
* @param status - set desktop notifications allowed status * @param status - set desktop notifications allowed status
*/ */
void allowDesktopNotificationsChanged(bool isAllowed); void allowDesktopNotificationsChanged(bool isAllowed);

View file

@ -614,7 +614,7 @@ void SyncEngine::slotFolderDiscovered(bool local, const QString &folder)
emit transmissionProgress(*_progressInfo); emit transmissionProgress(*_progressInfo);
} }
void SyncEngine::slotRootEtagReceived(const QString &e, const QDateTime &time) void SyncEngine::slotRootEtagReceived(const QByteArray &e, const QDateTime &time)
{ {
if (_remoteRootEtag.isEmpty()) { if (_remoteRootEtag.isEmpty()) {
qCDebug(lcEngine) << "Root etag:" << e; qCDebug(lcEngine) << "Root etag:" << e;

View file

@ -138,7 +138,7 @@ public:
signals: signals:
// During update, before reconcile // During update, before reconcile
void rootEtag(const QString &, const QDateTime &); void rootEtag(const QByteArray &, const QDateTime &);
// after the above signals. with the items that actually need propagating // after the above signals. with the items that actually need propagating
void aboutToPropagate(SyncFileItemVector &); void aboutToPropagate(SyncFileItemVector &);
@ -174,7 +174,7 @@ signals:
private slots: private slots:
void slotFolderDiscovered(bool local, const QString &folder); void slotFolderDiscovered(bool local, const QString &folder);
void slotRootEtagReceived(const QString &, const QDateTime &time); void slotRootEtagReceived(const QByteArray &, const QDateTime &time);
/** When the discovery phase discovers an item */ /** When the discovery phase discovers an item */
void slotItemDiscovered(const SyncFileItemPtr &item); void slotItemDiscovered(const SyncFileItemPtr &item);
@ -234,7 +234,7 @@ private:
bool _syncRunning; bool _syncRunning;
QString _localPath; QString _localPath;
QString _remotePath; QString _remotePath;
QString _remoteRootEtag; QByteArray _remoteRootEtag;
SyncJournalDb *_journal; SyncJournalDb *_journal;
QScopedPointer<DiscoveryPhase> _discoveryPhase; QScopedPointer<DiscoveryPhase> _discoveryPhase;
QSharedPointer<OwncloudPropagator> _propagator; QSharedPointer<OwncloudPropagator> _propagator;