diff --git a/src/libsync/propagateuploadng.cpp b/src/libsync/propagateuploadng.cpp index d8219b759e13a..dac82eef035d8 100644 --- a/src/libsync/propagateuploadng.cpp +++ b/src/libsync/propagateuploadng.cpp @@ -82,7 +82,7 @@ QByteArray PropagateUploadFileNG::destinationHeader() const const auto davUrl = Utility::trailingSlashPath(propagator()->account()->davUrl().toString()); const auto remotePath = Utility::noLeadingSlashPath(propagator()->fullRemotePath(_fileToUpload._file)); const auto destination = QString(davUrl + remotePath); - return destination.toUtf8(); + return QUrl::toPercentEncoding(destination, "/"); } void PropagateUploadFileNG::doStartUpload() diff --git a/test/testchunkingng.cpp b/test/testchunkingng.cpp index 1a3c0160a0943..636729bf71294 100644 --- a/test/testchunkingng.cpp +++ b/test/testchunkingng.cpp @@ -127,6 +127,32 @@ private slots: QCOMPARE(fakeFolder.uploadState().children.count(), 2); // the transfer was done with chunking } + void testDestinationHeaderPercentEncoding() + { + FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()}; + fakeFolder.syncEngine().account()->setCapabilities({ { "dav", QVariantMap{ {"chunking", "1.0"} } } }); + setChunkSize(fakeFolder.syncEngine(), 1 * 1000 * 1000); + + QByteArray destinationHeader; + fakeFolder.setServerOverride([&destinationHeader](QNetworkAccessManager::Operation, const QNetworkRequest &request, QIODevice *) -> QNetworkReply * { + if (destinationHeader.isEmpty() && request.hasRawHeader("Destination")) { + destinationHeader = request.rawHeader("Destination"); + } + return nullptr; + }); + + const QString filePath = QStringLiteral("A/SQ-0.5%BF-150/a0"); + const int size = 2 * 1000 * 1000; // 2 MB + + fakeFolder.localModifier().mkdir(QStringLiteral("A/SQ-0.5%BF-150")); + fakeFolder.localModifier().insert(filePath, size); + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(!destinationHeader.isEmpty()); + QVERIFY(destinationHeader.contains("SQ-0.5%25BF-150")); + QVERIFY(destinationHeader.contains("/A/SQ-0.5%25BF-150/")); + QVERIFY(!destinationHeader.contains("%2F")); + } + // Test resuming when there's a confusing chunk added void testResume1() { FakeFolder fakeFolder{FileInfo::A12_B12_C12_S12()};