ETagJob: Depth 0 for server >= 8.1 #3730

This commit is contained in:
Markus Goetz 2015-10-16 11:52:27 +02:00
parent 5cac90b3eb
commit ccec186b98
9 changed files with 52 additions and 15 deletions

View file

@ -44,9 +44,9 @@ AbstractNetworkJob::AbstractNetworkJob(AccountPtr account, const QString &path,
: QObject(parent) : QObject(parent)
, _timedout(false) , _timedout(false)
, _followRedirects(false) , _followRedirects(false)
, _account(account)
, _ignoreCredentialFailure(false) , _ignoreCredentialFailure(false)
, _reply(0) , _reply(0)
, _account(account)
, _path(path) , _path(path)
, _redirectCount(0) , _redirectCount(0)
{ {

View file

@ -91,11 +91,12 @@ private slots:
void slotFinished(); void slotFinished();
virtual void slotTimeout(); virtual void slotTimeout();
protected:
AccountPtr _account;
private: private:
QNetworkReply* addTimer(QNetworkReply *reply); QNetworkReply* addTimer(QNetworkReply *reply);
bool _ignoreCredentialFailure; bool _ignoreCredentialFailure;
QPointer<QNetworkReply> _reply; // (QPointer because the NetworkManager may be destroyed before the jobs at exit) QPointer<QNetworkReply> _reply; // (QPointer because the NetworkManager may be destroyed before the jobs at exit)
AccountPtr _account;
QString _path; QString _path;
QTimer _timer; QTimer _timer;
int _redirectCount; int _redirectCount;

View file

@ -478,9 +478,25 @@ QString Account::serverVersion()
return _serverVersion; return _serverVersion;
} }
int Account::serverVersionInt()
{
// FIXME: Use Qt 5.5 QVersionNumber
auto components = serverVersion().split('.');
return (components.value(0).toInt() << 16)
+ (components.value(1).toInt() << 8)
+ components.value(2).toInt();
}
void Account::setServerVersion(const QString& version) void Account::setServerVersion(const QString& version)
{ {
_serverVersion = version; _serverVersion = version;
} }
bool Account::rootEtagChangesNotOnlySubFolderEtags()
{
return (serverVersionInt() >= 0x080100);
}
} // namespace OCC } // namespace OCC

View file

@ -154,6 +154,10 @@ public:
const Capabilities &capabilities() const; const Capabilities &capabilities() const;
void setServerVersion(const QString &version); void setServerVersion(const QString &version);
QString serverVersion(); QString serverVersion();
int serverVersionInt();
// Fixed from 8.1 https://github.com/owncloud/client/issues/3730
bool rootEtagChangesNotOnlySubFolderEtags();
void clearCookieJar(); void clearCookieJar();
void lendCookieJarTo(QNetworkAccessManager *guest); void lendCookieJarTo(QNetworkAccessManager *guest);

View file

@ -327,6 +327,10 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(QString file,QMap
//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")) {
_etagConcatenation += map.value("getetag"); _etagConcatenation += map.value("getetag");
if (_firstEtag.isEmpty()) {
_firstEtag = map.value("getetag"); // for directory itself
}
} }
} }
@ -339,6 +343,7 @@ void DiscoverySingleDirectoryJob::lsJobFinishedWithoutErrorSlot()
deleteLater(); deleteLater();
return; return;
} }
emit etag(_firstEtag);
emit etagConcatenation(_etagConcatenation); emit etagConcatenation(_etagConcatenation);
emit finishedWithResult(_results); emit finishedWithResult(_results);
deleteLater(); deleteLater();
@ -410,6 +415,8 @@ void DiscoveryMainThread::doOpendirSlot(QString subPath, DiscoveryDirectoryResul
this, SLOT(singleDirectoryJobFirstDirectoryPermissionsSlot(QString))); this, SLOT(singleDirectoryJobFirstDirectoryPermissionsSlot(QString)));
QObject::connect(_singleDirJob, SIGNAL(etagConcatenation(QString)), QObject::connect(_singleDirJob, SIGNAL(etagConcatenation(QString)),
this, SIGNAL(etagConcatenation(QString))); this, SIGNAL(etagConcatenation(QString)));
QObject::connect(_singleDirJob, SIGNAL(etag(QString)),
this, SIGNAL(etag(QString)));
_singleDirJob->start(); _singleDirJob->start();
} }

View file

@ -87,6 +87,7 @@ public:
signals: signals:
void firstDirectoryPermissions(const QString &); void firstDirectoryPermissions(const QString &);
void etagConcatenation(const QString &); void etagConcatenation(const QString &);
void etag(const QString &);
void finishedWithResult(const QList<FileStatPointer> &); void finishedWithResult(const QList<FileStatPointer> &);
void finishedWithError(int csyncErrnoCode, QString msg); void finishedWithError(int csyncErrnoCode, QString msg);
private slots: private slots:
@ -97,6 +98,7 @@ private:
QList<FileStatPointer> _results; QList<FileStatPointer> _results;
QString _subPath; QString _subPath;
QString _etagConcatenation; QString _etagConcatenation;
QString _firstEtag;
AccountPtr _account; AccountPtr _account;
bool _ignoredFirst; bool _ignoredFirst;
QPointer<LsColJob> _lsColJob; QPointer<LsColJob> _lsColJob;
@ -134,7 +136,8 @@ public slots:
void slotGetSizeFinishedWithError(); void slotGetSizeFinishedWithError();
void slotGetSizeResult(const QVariantMap&); void slotGetSizeResult(const QVariantMap&);
signals: signals:
void etagConcatenation(QString); void etag(const QString &);
void etagConcatenation(const QString &);
public: public:
void setupHooks(DiscoveryJob* discoveryJob, const QString &pathPrefix); void setupHooks(DiscoveryJob* discoveryJob, const QString &pathPrefix);
}; };

View file

@ -46,11 +46,16 @@ RequestEtagJob::RequestEtagJob(AccountPtr account, const QString &path, QObject
void RequestEtagJob::start() void RequestEtagJob::start()
{ {
QNetworkRequest req; QNetworkRequest req;
// Let's always request all entries inside a directory. There are/were bugs in the server if (_account && _account->rootEtagChangesNotOnlySubFolderEtags()) {
// where a root or root-folder ETag is not updated when its contents change. We work around // Fixed from 8.1 https://github.com/owncloud/client/issues/3730
// this by concatenating the ETags of the root and its contents. req.setRawHeader("Depth", "0");
req.setRawHeader("Depth", "1"); } else {
// See https://github.com/owncloud/core/issues/5255 and others // Let's always request all entries inside a directory. There are/were bugs in the server
// where a root or root-folder ETag is not updated when its contents change. We work around
// this by concatenating the ETags of the root and its contents.
req.setRawHeader("Depth", "1");
// See https://github.com/owncloud/core/issues/5255 and others
}
QByteArray xml("<?xml version=\"1.0\" ?>\n" QByteArray xml("<?xml version=\"1.0\" ?>\n"
"<d:propfind xmlns:d=\"DAV:\">\n" "<d:propfind xmlns:d=\"DAV:\">\n"

View file

@ -513,11 +513,7 @@ void PropagateUploadFileQNAM::startNextChunk()
if (!env.isEmpty()) { if (!env.isEmpty()) {
parallelChunkUpload = env != "false" && env != "0"; parallelChunkUpload = env != "false" && env != "0";
} else { } else {
auto version = _propagator->account()->serverVersion(); int versionNum = _propagator->account()->serverVersionInt();
auto components = version.split('.');
int versionNum = (components.value(0).toInt() << 16)
+ (components.value(1).toInt() << 8)
+ components.value(2).toInt();
if (versionNum < 0x080003) { if (versionNum < 0x080003) {
// Disable parallel chunk upload severs older than 8.0.3 to avoid too many // Disable parallel chunk upload severs older than 8.0.3 to avoid too many
// internal sever errors (#2743, #2938) // internal sever errors (#2743, #2938)

View file

@ -676,8 +676,13 @@ void SyncEngine::startSync()
_discoveryMainThread = new DiscoveryMainThread(account()); _discoveryMainThread = new DiscoveryMainThread(account());
_discoveryMainThread->setParent(this); _discoveryMainThread->setParent(this);
connect(this, SIGNAL(finished()), _discoveryMainThread, SLOT(deleteLater())); connect(this, SIGNAL(finished()), _discoveryMainThread, SLOT(deleteLater()));
connect(_discoveryMainThread, SIGNAL(etagConcatenation(QString)), this, SLOT(slotRootEtagReceived(QString))); qDebug() << "=====Server" << account()->serverVersion()
<< QString("rootEtagChangesNotOnlySubFolderEtags=%1").arg(account()->rootEtagChangesNotOnlySubFolderEtags());
if (account()->rootEtagChangesNotOnlySubFolderEtags()) {
connect(_discoveryMainThread, SIGNAL(etag(QString)), this, SLOT(slotRootEtagReceived(QString)));
} else {
connect(_discoveryMainThread, SIGNAL(etagConcatenation(QString)), this, SLOT(slotRootEtagReceived(QString)));
}
DiscoveryJob *discoveryJob = new DiscoveryJob(_csync_ctx); DiscoveryJob *discoveryJob = new DiscoveryJob(_csync_ctx);
discoveryJob->_selectiveSyncBlackList = selectiveSyncBlackList; discoveryJob->_selectiveSyncBlackList = selectiveSyncBlackList;