diff --git a/domain-server/resources/web/content/js/content.js b/domain-server/resources/web/content/js/content.js index 61fee425ff..d581ddaf85 100644 --- a/domain-server/resources/web/content/js/content.js +++ b/domain-server/resources/web/content/js/content.js @@ -44,7 +44,7 @@ $(document).ready(function(){ var fileSize = file.size; var filename = file.name; - var CHUNK_SIZE = 16384; + var CHUNK_SIZE = 65536; if (offset == undefined) { offset = 0; } @@ -58,9 +58,10 @@ $(document).ready(function(){ var ajaxParams = { url: '/content/upload', type: 'POST', - timeout: 30000, + timeout: 30000, // 30 s cache: false, processData: false, + contentType: false, data: chunkFormData }; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index b540592d7e..fd378cb39b 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -2258,41 +2258,63 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url // check the file extension to see what kind of file this is // to make sure we handle this filetype for a content restore auto dispositionValue = QString(firstFormData.first.value("Content-Disposition")); - auto formDataFilenameRegex = QRegExp("filename=\"(.+)\""); - auto matchIndex = formDataFilenameRegex.indexIn(dispositionValue); + QRegExp formDataFieldsRegex(R":(name="(restore-file.*)".*filename="(.+)"):"); + auto matchIndex = formDataFieldsRegex.indexIn(dispositionValue); + QString formItemName = ""; QString uploadedFilename = ""; if (matchIndex != -1) { - uploadedFilename = formDataFilenameRegex.cap(1); + formItemName = formDataFieldsRegex.cap(1); + uploadedFilename = formDataFieldsRegex.cap(2); } - if (uploadedFilename.endsWith(".json", Qt::CaseInsensitive) - || uploadedFilename.endsWith(".json.gz", Qt::CaseInsensitive)) { - // invoke our method to hand the new octree file off to the octree server - QMetaObject::invokeMethod(this, "handleOctreeFileReplacement", - Qt::QueuedConnection, Q_ARG(QByteArray, firstFormData.second)); - - // respond with a 200 for success + _pendingUploadedContent += firstFormData.second; + if (formItemName == "restore-file-chunk") { + // Received another chunk connection->respond(HTTPConnection::StatusCode200); - } else if (uploadedFilename.endsWith(".zip", Qt::CaseInsensitive)) { - auto deferred = makePromise("recoverFromUploadedBackup"); + } else if (formItemName == "restore-file-chunk-final") { + if (uploadedFilename.endsWith(".json", Qt::CaseInsensitive) + || uploadedFilename.endsWith(".json.gz", Qt::CaseInsensitive)) { + // invoke our method to hand the new octree file off to the octree server + QMetaObject::invokeMethod(this, "handleOctreeFileReplacement", + Qt::QueuedConnection, Q_ARG(QByteArray, _pendingUploadedContent)); + _pendingUploadedContent.clear(); + // respond with a 200 for success + connection->respond(HTTPConnection::StatusCode200); + } else if (formItemName == "restore-file") { + if (uploadedFilename.endsWith(".json", Qt::CaseInsensitive) + || uploadedFilename.endsWith(".json.gz", Qt::CaseInsensitive)) { + // invoke our method to hand the new octree file off to the octree server + QMetaObject::invokeMethod(this, "handleOctreeFileReplacement", + Qt::QueuedConnection, Q_ARG(QByteArray, firstFormData.second)); - deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) { - if (!connectionPtr) { - return; + _pendingUploadedContent.clear(); + // respond with a 200 for success + connection->respond(HTTPConnection::StatusCode200); + } else if (uploadedFilename.endsWith(".zip", Qt::CaseInsensitive)) { + auto deferred = makePromise("recoverFromUploadedBackup"); + + deferred->then([connectionPtr, JSON_MIME_TYPE](QString error, QVariantMap result) { + if (!connectionPtr) { + return; + } + + QJsonObject rootJSON; + auto success = result["success"].toBool(); + rootJSON["success"] = success; + QJsonDocument docJSON(rootJSON); + connectionPtr->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(), + JSON_MIME_TYPE.toUtf8()); + }); + + _contentManager->recoverFromUploadedBackup(deferred, firstFormData.second); + _pendingUploadedContent.clear(); + + return true; } - - QJsonObject rootJSON; - auto success = result["success"].toBool(); - rootJSON["success"] = success; - QJsonDocument docJSON(rootJSON); - connectionPtr->respond(success ? HTTPConnection::StatusCode200 : HTTPConnection::StatusCode400, docJSON.toJson(), - JSON_MIME_TYPE.toUtf8()); - }); - - _contentManager->recoverFromUploadedBackup(deferred, firstFormData.second); - - return true; + } else { + connection->respond(HTTPConnection::StatusCode400); + } } else { // we don't have handling for this filetype, send back a 400 for failure connection->respond(HTTPConnection::StatusCode400); diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index e2bddc1aa5..db50af546e 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -281,6 +281,8 @@ private: QHash> _pendingOAuthConnections; + QByteArray _pendingUploadedContent; + QThread _assetClientThread; };