Split getting chunk upload folder from chunkUrl as this was previously misleading...
authorClaudio Cambra <claudio.cambra@nextcloud.com>
Fri, 28 Jul 2023 07:10:52 +0000 (15:10 +0800)
committerMatthieu Gallien <matthieu_gallien@yahoo.fr>
Thu, 31 Aug 2023 13:25:00 +0000 (15:25 +0200)
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
src/libsync/propagateupload.h
src/libsync/propagateuploadng.cpp

index 914ad24f1678391d13af9ebbe26d08bba34591a9..86a0e82ebd1fcf4469f651bdc5a27f27099f0997 100644 (file)
@@ -408,11 +408,8 @@ private:
         QString originalName;
     };
 
-    /**
-     * Return the URL of a chunk.
-     * If chunk == -1, returns the URL of the parent folder containing the chunks
-     */
-    QUrl chunkUrl(int chunk = -1);
+    QUrl chunkUploadFolderUrl() const;
+    QUrl chunkUrl(const int chunk) const;
 
     void startNewUpload();
     void startNextChunk();
index e0458b2ef58075303437194823e8d95fb7f328a1..9d3ffb0b60f5f24e75a9de5f484bbac6ce08928b 100644 (file)
 
 namespace OCC {
 
-QUrl PropagateUploadFileNG::chunkUrl(int chunk)
+constexpr auto relativeUploadsPath = "remote.php/dav/uploads/";
+
+QUrl PropagateUploadFileNG::chunkUploadFolderUrl() const
 {
-    QString path = QLatin1String("remote.php/dav/uploads/")
-        + propagator()->account()->davUser()
-        + QLatin1Char('/') + QString::number(_transferId);
-    if (chunk >= 0) {
-        // We need to do add leading 0 because the server orders the chunk alphabetically
-        path += QLatin1Char('/') + QString::number(chunk).rightJustified(16, '0'); // 1e16 is 10 petabyte
-    }
-    return Utility::concatUrlPath(propagator()->account()->url(), path);
+    const auto userUploadPath = relativeUploadsPath + propagator()->account()->davUser();
+    const auto chunksUploadPath = userUploadPath + QLatin1Char('/') + QString::number(_transferId);
+    return Utility::concatUrlPath(propagator()->account()->url(), chunksUploadPath);
+}
+
+QUrl PropagateUploadFileNG::chunkUrl(const int chunk) const
+{
+    constexpr auto maxChunkDigits = 5; // Chunk V2: max num of chunks is 10000
+
+    // We need to do add leading 0 because the server orders the chunk alphabetically
+    const auto chunkNumString = QString("%1").arg(chunk, maxChunkDigits, 10, QChar('0'));
+    return Utility::concatUrlPath(chunkUploadFolderUrl(), chunkNumString);
 }
 
 /*
@@ -87,11 +93,10 @@ void PropagateUploadFileNG::doStartUpload()
     if (_item->_modtime <= 0) {
         qCWarning(lcPropagateUpload()) << "invalid modified time" << _item->_file << _item->_modtime;
     }
-    if (progressInfo._valid && progressInfo.isChunked() && progressInfo._modtime == _item->_modtime
-            && progressInfo._size == _item->_size) {
+    if (progressInfo._valid && progressInfo.isChunked() && progressInfo._modtime == _item->_modtime && progressInfo._size == _item->_size) {
         _transferId = progressInfo._transferid;
-        auto url = chunkUrl();
-        auto job = new LsColJob(propagator()->account(), url, this);
+
+        const auto job = new LsColJob(propagator()->account(), chunkUploadFolderUrl(), this);
         _jobs.append(job);
         job->setProperties(QList<QByteArray>() << "resourcetype"
                                                << "getcontentlength");
@@ -107,7 +112,7 @@ void PropagateUploadFileNG::doStartUpload()
         // The upload info is stale. remove the stale chunks on the server
         _transferId = progressInfo._transferid;
         // Fire and forget. Any error will be ignored.
-        (new DeleteJob(propagator()->account(), chunkUrl(), this))->start();
+        (new DeleteJob(propagator()->account(), chunkUploadFolderUrl(), this))->start();
         // startNewUpload will reset the _transferId and the UploadInfo in the db.
     }
 
@@ -116,12 +121,14 @@ void PropagateUploadFileNG::doStartUpload()
 
 void PropagateUploadFileNG::slotPropfindIterate(const QString &name, const QMap<QString, QString> &properties)
 {
-    if (name == chunkUrl().path()) {
+    if (name == chunkUploadFolderUrl().path()) {
         return; // skip the info about the path itself
     }
+
     bool ok = false;
     QString chunkName = name.mid(name.lastIndexOf('/') + 1);
     auto chunkId = chunkName.toLongLong(&ok);
+
     if (ok) {
         ServerChunkInfo chunkinfo = { properties["getcontentlength"].toLongLong(), chunkName };
         _serverChunks[chunkId] = chunkinfo;
@@ -151,7 +158,7 @@ void PropagateUploadFileNG::slotPropfindFinished()
 
         // Wipe the old chunking data.
         // Fire and forget. Any error will be ignored.
-        (new DeleteJob(propagator()->account(), chunkUrl(), this))->start();
+        (new DeleteJob(propagator()->account(), chunkUploadFolderUrl(), this))->start();
 
         propagator()->_activeJobList.append(this);
         startNewUpload();
@@ -169,7 +176,7 @@ void PropagateUploadFileNG::slotPropfindFinished()
         // we should remove the later chunks. Otherwise when we do dynamic chunk sizing, we may end up
         // with corruptions if there are too many chunks, or if we abort and there are still stale chunks.
         for (const auto &serverChunk : qAsConst(_serverChunks)) {
-            auto job = new DeleteJob(propagator()->account(), Utility::concatUrlPath(chunkUrl(), serverChunk.originalName), this);
+            auto job = new DeleteJob(propagator()->account(), Utility::concatUrlPath(chunkUploadFolderUrl(), serverChunk.originalName), this);
             QObject::connect(job, &DeleteJob::finishedSignal, this, &PropagateUploadFileNG::slotDeleteJobFinished);
             _jobs.append(job);
             job->start();
@@ -259,7 +266,7 @@ void PropagateUploadFileNG::startNewUpload()
 
     // But we should send the temporary (or something) one.
     headers["OC-Total-Length"] = QByteArray::number(_fileToUpload._size);
-    auto job = new MkColJob(propagator()->account(), chunkUrl(), headers, this);
+    const auto job = new MkColJob(propagator()->account(), chunkUploadFolderUrl(), headers, this);
 
     connect(job, &MkColJob::finishedWithError,
         this, &PropagateUploadFileNG::slotMkColFinished);
@@ -311,7 +318,7 @@ void PropagateUploadFileNG::finishUpload()
     const auto fileSize = _fileToUpload._size;
     headers[QByteArrayLiteral("OC-Total-Length")] = QByteArray::number(fileSize);
 
-    const auto job = new MoveJob(propagator()->account(), Utility::concatUrlPath(chunkUrl(), "/.file"), destination, headers, this);
+    const auto job = new MoveJob(propagator()->account(), Utility::concatUrlPath(chunkUploadFolderUrl(), "/.file"), destination, headers, this);
     _jobs.append(job);
     connect(job, &MoveJob::finishedSignal, this, &PropagateUploadFileNG::slotMoveJobFinished);
     connect(job, &QObject::destroyed, this, &PropagateUploadFileCommon::slotJobDestroyed);