From: Matthieu Gallien Date: Thu, 10 Feb 2022 15:40:15 +0000 (+0100) Subject: ensure that bulk upload network job errors are handled X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~12^2~17^2~153^2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=e4590d7a3b4dd6f29ffdc64f8c606f463042104c;p=nextcloud-desktop.git ensure that bulk upload network job errors are handled in case we get a network error during bulk propagator POST network request, report all files within this upload as files in error that will then be sent using the plain old WebDAV protocol Signed-off-by: Matthieu Gallien --- diff --git a/src/libsync/bulkpropagatorjob.cpp b/src/libsync/bulkpropagatorjob.cpp index 3b99acaf1..4c713bd81 100644 --- a/src/libsync/bulkpropagatorjob.cpp +++ b/src/libsync/bulkpropagatorjob.cpp @@ -407,12 +407,18 @@ void BulkPropagatorJob::slotPutFinished() slotJobDestroyed(job); // remove it from the _jobs list + const auto jobError = job->reply()->error(); + const auto replyData = job->reply()->readAll(); const auto replyJson = QJsonDocument::fromJson(replyData); const auto fullReplyObject = replyJson.object(); for (const auto &singleFile : _filesToUpload) { if (!fullReplyObject.contains(singleFile._remotePath)) { + if (jobError != QNetworkReply::NoError) { + singleFile._item->_status = SyncFileItem::NormalError; + abortWithError(singleFile._item, SyncFileItem::NormalError, tr("Network Error: %1").arg(jobError)); + } continue; } const auto singleReplyObject = fullReplyObject[singleFile._remotePath].toObject(); diff --git a/test/testsyncengine.cpp b/test/testsyncengine.cpp index 1f77dc050..d2c865b7c 100644 --- a/test/testsyncengine.cpp +++ b/test/testsyncengine.cpp @@ -931,6 +931,57 @@ private slots: QCOMPARE(nPUT, 6); QCOMPARE(nPOST, 0); } + + /** + * Checks whether subsequent large uploads are skipped after a 507 error + */ + void testNetworkErrorsWithBulkUpload() + { + FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() }; + fakeFolder.syncEngine().account()->setCapabilities({ { "dav", QVariantMap{ {"bulkupload", "1.0"} } } }); + + // Disable parallel uploads + SyncOptions syncOptions; + syncOptions._parallelNetworkJobs = 0; + fakeFolder.syncEngine().setSyncOptions(syncOptions); + + int nPUT = 0; + int nPOST = 0; + fakeFolder.setServerOverride([&](QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * { + auto contentType = request.header(QNetworkRequest::ContentTypeHeader).toString(); + if (op == QNetworkAccessManager::PostOperation) { + ++nPOST; + if (contentType.startsWith(QStringLiteral("multipart/related; boundary="))) { + return new FakeErrorReply(op, request, this, 400); + } + return nullptr; + } else if (op == QNetworkAccessManager::PutOperation) { + ++nPUT; + } + return nullptr; + }); + + fakeFolder.localModifier().insert("A/big1", 1); + fakeFolder.localModifier().insert("A/big2", 1); + fakeFolder.localModifier().insert("A/big3", 1); + fakeFolder.localModifier().insert("A/big4", 1); + fakeFolder.localModifier().insert("A/big5", 1); + fakeFolder.localModifier().insert("A/big6", 1); + fakeFolder.localModifier().insert("A/big7", 1); + fakeFolder.localModifier().insert("A/big8", 1); + fakeFolder.localModifier().insert("B/big8", 1); + + QVERIFY(!fakeFolder.syncOnce()); + QCOMPARE(nPUT, 0); + QCOMPARE(nPOST, 1); + nPUT = 0; + nPOST = 0; + + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(nPUT, 9); + QCOMPARE(nPOST, 0); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + } }; QTEST_GUILESS_MAIN(TestSyncEngine)