ETagJob: Depth 0 for server >= 8.1 #3730
authorMarkus Goetz <markus@woboq.com>
Fri, 16 Oct 2015 09:52:27 +0000 (11:52 +0200)
committerMarkus Goetz <markus@woboq.com>
Mon, 19 Oct 2015 13:31:27 +0000 (15:31 +0200)
src/libsync/abstractnetworkjob.cpp
src/libsync/abstractnetworkjob.h
src/libsync/account.cpp
src/libsync/account.h
src/libsync/discoveryphase.cpp
src/libsync/discoveryphase.h
src/libsync/networkjobs.cpp
src/libsync/propagateupload.cpp
src/libsync/syncengine.cpp

index 599e5be9a9ee8cbd0a95501485c2a2bde338ae25..ad874ed30c7424ac6330cbe68435db00f401b522 100644 (file)
@@ -44,9 +44,9 @@ AbstractNetworkJob::AbstractNetworkJob(AccountPtr account, const QString &path,
     : QObject(parent)
     , _timedout(false)
     , _followRedirects(false)
+    , _account(account)
     , _ignoreCredentialFailure(false)
     , _reply(0)
-    , _account(account)
     , _path(path)
     , _redirectCount(0)
 {
index c471cca4c1d456d9ae1dc49c59fd2666030d4735..08e71cf8b1f71e31618d1827f420e1517ca9ad58 100644 (file)
@@ -91,11 +91,12 @@ private slots:
     void slotFinished();
     virtual void slotTimeout();
 
+protected:
+    AccountPtr _account;
 private:
     QNetworkReply* addTimer(QNetworkReply *reply);
     bool _ignoreCredentialFailure;
     QPointer<QNetworkReply> _reply; // (QPointer because the NetworkManager may be destroyed before the jobs at exit)
-    AccountPtr _account;
     QString _path;
     QTimer _timer;
     int _redirectCount;
index cbf537f8385e035a09fce10e706e14a36a6729c9..73a68872ca5dc6012e5ebdcf0e14bbb8cd24dab1 100644 (file)
@@ -478,9 +478,25 @@ QString Account::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)
 {
     _serverVersion = version;
 }
 
+bool Account::rootEtagChangesNotOnlySubFolderEtags()
+{
+    return (serverVersionInt() >= 0x080100);
+}
+
+
+
 } // namespace OCC
index e142a9a4936ffdb832752f30ee11a9e07c092d0f..cb706c42b96b24940dc1f21b69f19de778b0dbc6 100644 (file)
@@ -154,6 +154,10 @@ public:
     const Capabilities &capabilities() const;
     void setServerVersion(const QString &version);
     QString serverVersion();
+    int serverVersionInt();
+
+    // Fixed from 8.1 https://github.com/owncloud/client/issues/3730
+    bool rootEtagChangesNotOnlySubFolderEtags();
 
     void clearCookieJar();
     void lendCookieJarTo(QNetworkAccessManager *guest);
index dcf2500ae1a7c4dcaffe6dd3559dd28efd855a3d..8273d7dc3dd2cfbe714894abd63e1a9fd07caf3e 100644 (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.
     if (map.contains("getetag")) {
        _etagConcatenation += map.value("getetag");
+
+       if (_firstEtag.isEmpty()) {
+           _firstEtag = map.value("getetag"); // for directory itself
+       }
     }
 }
 
@@ -339,6 +343,7 @@ void DiscoverySingleDirectoryJob::lsJobFinishedWithoutErrorSlot()
         deleteLater();
         return;
     }
+    emit etag(_firstEtag);
     emit etagConcatenation(_etagConcatenation);
     emit finishedWithResult(_results);
     deleteLater();
@@ -410,6 +415,8 @@ void DiscoveryMainThread::doOpendirSlot(QString subPath, DiscoveryDirectoryResul
                      this, SLOT(singleDirectoryJobFirstDirectoryPermissionsSlot(QString)));
     QObject::connect(_singleDirJob, SIGNAL(etagConcatenation(QString)),
                      this, SIGNAL(etagConcatenation(QString)));
+    QObject::connect(_singleDirJob, SIGNAL(etag(QString)),
+                     this, SIGNAL(etag(QString)));
     _singleDirJob->start();
 }
 
index 0c320a56190ff85ef6a3b1131f9516b28ef4d205..71d126a07e841e6bc2736d9e1766d573f78c2dbf 100644 (file)
@@ -87,6 +87,7 @@ public:
 signals:
     void firstDirectoryPermissions(const QString &);
     void etagConcatenation(const QString &);
+    void etag(const QString &);
     void finishedWithResult(const QList<FileStatPointer> &);
     void finishedWithError(int csyncErrnoCode, QString msg);
 private slots:
@@ -97,6 +98,7 @@ private:
     QList<FileStatPointer> _results;
     QString _subPath;
     QString _etagConcatenation;
+    QString _firstEtag;
     AccountPtr _account;
     bool _ignoredFirst;
     QPointer<LsColJob> _lsColJob;
@@ -134,7 +136,8 @@ public slots:
     void slotGetSizeFinishedWithError();
     void slotGetSizeResult(const QVariantMap&);
 signals:
-    void etagConcatenation(QString);
+    void etag(const QString &);
+    void etagConcatenation(const QString &);
 public:
     void setupHooks(DiscoveryJob* discoveryJob, const QString &pathPrefix);
 };
index 0d7f8b6820350ede422e2f1a3fa0cdbad86a4aa7..2a62ee455320ba68a19c35b3646e620811ccf7b5 100644 (file)
@@ -46,11 +46,16 @@ RequestEtagJob::RequestEtagJob(AccountPtr account, const QString &path, QObject
 void RequestEtagJob::start()
 {
     QNetworkRequest req;
-    // 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
+    if (_account && _account->rootEtagChangesNotOnlySubFolderEtags()) {
+        // Fixed from 8.1 https://github.com/owncloud/client/issues/3730
+        req.setRawHeader("Depth", "0");
+    } else {
+        // 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"
                    "<d:propfind xmlns:d=\"DAV:\">\n"
index 905b379db8f087f2a470627cab6ec18a74dda2c4..4fe2182f2aee854c817e4676993b7172b2164250 100644 (file)
@@ -513,11 +513,7 @@ void PropagateUploadFileQNAM::startNextChunk()
     if (!env.isEmpty()) {
         parallelChunkUpload = env != "false" && env != "0";
     } else {
-        auto version = _propagator->account()->serverVersion();
-        auto components = version.split('.');
-        int versionNum = (components.value(0).toInt() << 16)
-                       + (components.value(1).toInt() << 8)
-                       + components.value(2).toInt();
+        int versionNum = _propagator->account()->serverVersionInt();
         if (versionNum < 0x080003) {
             // Disable parallel chunk upload severs older than 8.0.3 to avoid too many
             // internal sever errors (#2743, #2938)
index 807af160f4981ee101b780e32384f2c0f297b329..ca2f8ff7c99966a3ecede60d7400e5cbba8aebc6 100644 (file)
@@ -676,8 +676,13 @@ void SyncEngine::startSync()
     _discoveryMainThread = new DiscoveryMainThread(account());
     _discoveryMainThread->setParent(this);
     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->_selectiveSyncBlackList = selectiveSyncBlackList;