mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-22 21:15:55 +03:00
Use byte array for etag
This commit is contained in:
parent
5a7fd3f316
commit
5b457a1663
11 changed files with 40 additions and 35 deletions
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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--;
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue