From 2a7e22bf317698f2d5d94ce011b8b07c11ef6b43 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 19 Nov 2018 15:26:08 -0800 Subject: [PATCH] Identify initial chunk of an upload so as to be more resilient --- .../resources/web/content/js/content.js | 10 ++++++++-- domain-server/src/DomainServer.cpp | 16 ++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/domain-server/resources/web/content/js/content.js b/domain-server/resources/web/content/js/content.js index afee2cc8a9..85bd9e68b3 100644 --- a/domain-server/resources/web/content/js/content.js +++ b/domain-server/resources/web/content/js/content.js @@ -43,7 +43,13 @@ $(document).ready(function(){ var chunk = file.slice(offset, offset + nextChunkSize, file.type); var chunkFormData = new FormData(); - var formItemName = isFinal ? 'restore-file-chunk-final' : 'restore-file-chunk'; + var formItemName = 'restore-file-chunk'; + if (offset == 0) { + formItemName = isFinal ? 'restore-file-chunk-only' : 'restore-file-chunk-initial'; + } else if (isFinal) { + formItemName = 'restore-file-chunk-final'; + } + chunkFormData.append(formItemName, chunk, filename); var ajaxParams = { url: '/content/upload', @@ -57,7 +63,7 @@ $(document).ready(function(){ }; var ajaxObject = $.ajax(ajaxParams); - ajaxObject.fail(function(jqXHR, textStatus, errorThrown) { + ajaxObject.fail(function (jqXHR, textStatus, errorThrown) { showErrorMessage( "Error", "There was a problem restoring domain content.\n" diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 2a5ada729c..2d1abc8c71 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -2523,12 +2523,20 @@ bool DomainServer::processPendingContent(HTTPConnection* connection, QString ite QByteArray sessionIdBytes = connection->requestHeader(UPLOAD_SESSION_KEY); int sessionId = sessionIdBytes.toInt(); + bool newUpload = itemName == "restore-file" || itemName == "restore-file-chunk-initial" || itemName == "restore-file-chunk-only"; + if (filename.endsWith(".zip", Qt::CaseInsensitive)) { static const QString TEMPORARY_CONTENT_FILEPATH { QDir::tempPath() + "/hifiUploadContent_XXXXXX.zip" }; if (_pendingContentFiles.find(sessionId) == _pendingContentFiles.end()) { + if (!newUpload) { + return false; + } std::unique_ptr newTemp(new QTemporaryFile(TEMPORARY_CONTENT_FILEPATH)); _pendingContentFiles[sessionId] = std::move(newTemp); + } else if (newUpload) { + qCDebug(domain_server) << "New upload received using existing session ID"; + _pendingContentFiles[sessionId]->resize(0); } QTemporaryFile& _pendingFileContent = *_pendingContentFiles[sessionId]; @@ -2543,7 +2551,7 @@ bool DomainServer::processPendingContent(HTTPConnection* connection, QString ite // Respond immediately - will timeout if we wait for restore. connection->respond(HTTPConnection::StatusCode200); - if (itemName == "restore-file-chunk-final" || itemName == "restore-file") { + if (itemName == "restore-file" || itemName == "restore-file-chunk-final" || itemName == "restore-file-chunk-only") { auto deferred = makePromise("recoverFromUploadedBackup"); deferred->then([this, sessionId](QString error, QVariantMap result) { @@ -2554,11 +2562,15 @@ bool DomainServer::processPendingContent(HTTPConnection* connection, QString ite } } else if (filename.endsWith(".json", Qt::CaseInsensitive) || filename.endsWith(".json.gz", Qt::CaseInsensitive)) { + if (_pendingUploadedContents.find(sessionId) == _pendingUploadedContents.end() && !newUpload) { + qCDebug(domain_server) << "Json upload with invalid session ID received"; + return false; + } QByteArray& _pendingUploadedContent = _pendingUploadedContents[sessionId]; _pendingUploadedContent += dataChunk; connection->respond(HTTPConnection::StatusCode200); - if (itemName == "restore-file-chunk-final" || itemName == "restore-file") { + if (itemName == "restore-file" || itemName == "restore-file-chunk-final" || itemName == "restore-file-chunk-only") { // invoke our method to hand the new octree file off to the octree server QMetaObject::invokeMethod(this, "handleOctreeFileReplacement", Qt::QueuedConnection, Q_ARG(QByteArray, _pendingUploadedContent));