Restore content archives (zip) correctly; other tweaks

This commit is contained in:
Simon Walton 2018-11-08 16:34:02 -08:00
parent bb60324335
commit a21d10ad1b
3 changed files with 43 additions and 100 deletions

View file

@ -14,41 +14,18 @@ $(document).ready(function(){
return html; return html;
} }
function uploadInChunks(file) {
var fileSize = file.size;
var filename = file.name;
var CHUNK_SIZE = 16384;
for(p = 0; p <= fileSize; p += CHUNK_SIZE) {
var chunk = file.slice(p, p + CHUNK_SIZE, file.type);
var chunkFormData = new FormData();
chunkFormData.append('restore-file-chunk', chunk, filename);
var ajaxParams = {
url: '/content/upload',
type: 'POST',
async: false,
timeout: 60,
processData: false,
contentType: false,
data: chunkFormData
};
var ajaxObject = $.ajax(ajaxParams);
}
}
function uploadNextChunk(file, offset) function uploadNextChunk(file, offset)
{ {
if (offset == undefined) {
offset = 0;
}
var fileSize = file.size; var fileSize = file.size;
var filename = file.name; var filename = file.name;
var CHUNK_SIZE = 65536; var CHUNK_SIZE = 65536;
if (offset == undefined) {
offset = 0; var isFinal = Boolean(fileSize - offset <= CHUNK_SIZE);
}
var isFinal = fileSize - offset > CHUNK_SIZE ? false : true;
var nextChunkSize = Math.min(fileSize - offset, CHUNK_SIZE); var nextChunkSize = Math.min(fileSize - offset, CHUNK_SIZE);
var chunk = file.slice(offset, offset + CHUNK_SIZE, file.type); var chunk = file.slice(offset, offset + CHUNK_SIZE, file.type);
var chunkFormData = new FormData(); var chunkFormData = new FormData();
@ -127,38 +104,10 @@ $(document).ready(function(){
function() { function() {
var files = $('#' + RESTORE_SETTINGS_FILE_ID).prop('files'); var files = $('#' + RESTORE_SETTINGS_FILE_ID).prop('files');
var fileFormData = new FormData();
fileFormData.append('restore-file', files[0]);
showSpinnerAlert("Uploading content to restore"); showSpinnerAlert("Uploading content to restore");
uploadNextChunk(files[0]); uploadNextChunk(files[0]);
return;
// Previous one-upload method.
$.ajax({
url: '/content/upload',
type: 'POST',
timeout: 3600000, // Set timeout to 1h
cache: false,
processData: false,
contentType: false,
data: fileFormData
}).done(function(data, textStatus, jqXHR) {
isRestoring = true;
// immediately reload backup information since one should be restoring now
reloadBackupInformation();
swal.close();
}).fail(function(jqXHR, textStatus, errorThrown) {
showErrorMessage(
"Error",
"There was a problem restoring domain content.\n"
+ "Please ensure that the content archive or entity file is valid and try again."
);
});
} }
); );
}); });

View file

@ -2273,53 +2273,12 @@ bool DomainServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url
// Received another chunk // Received another chunk
connection->respond(HTTPConnection::StatusCode200); connection->respond(HTTPConnection::StatusCode200);
} else if (formItemName == "restore-file-chunk-final") { } else if (formItemName == "restore-file-chunk-final") {
if (uploadedFilename.endsWith(".json", Qt::CaseInsensitive) readPendingContent(connection, uploadedFilename);
|| 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") { } else if (formItemName == "restore-file") {
if (uploadedFilename.endsWith(".json", Qt::CaseInsensitive) readPendingContent(connection, uploadedFilename);
|| 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));
_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;
}
} else { } else {
connection->respond(HTTPConnection::StatusCode400); connection->respond(HTTPConnection::StatusCode400);
} }
} else {
// we don't have handling for this filetype, send back a 400 for failure
connection->respond(HTTPConnection::StatusCode400);
}
} else { } else {
// respond with a 400 for failure // respond with a 400 for failure
connection->respond(HTTPConnection::StatusCode400); connection->respond(HTTPConnection::StatusCode400);
@ -2568,6 +2527,39 @@ bool DomainServer::handleHTTPSRequest(HTTPSConnection* connection, const QUrl &u
} }
} }
void DomainServer::readPendingContent(HTTPConnection* connection, QString filename) {
if (filename.endsWith(".json", Qt::CaseInsensitive)
|| filename.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));
// respond with a 200 for success
connection->respond(HTTPConnection::StatusCode200);
_pendingUploadedContent.clear();
} else if (filename.endsWith(".zip", Qt::CaseInsensitive)) {
auto deferred = makePromise("recoverFromUploadedBackup");
QPointer<HTTPConnection> connectionPtr(connection);
const QString JSON_MIME_TYPE = "application/json";
deferred->then([connectionPtr, JSON_MIME_TYPE, this](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());
_pendingUploadedContent.clear();
});
_contentManager->recoverFromUploadedBackup(deferred, _pendingUploadedContent);
}
}
HTTPSConnection* DomainServer::connectionFromReplyWithState(QNetworkReply* reply) { HTTPSConnection* DomainServer::connectionFromReplyWithState(QNetworkReply* reply) {
// grab the UUID state property from the reply // grab the UUID state property from the reply
QUuid stateUUID = reply->property(STATE_QUERY_KEY.toLocal8Bit()).toUuid(); QUuid stateUUID = reply->property(STATE_QUERY_KEY.toLocal8Bit()).toUuid();

View file

@ -209,6 +209,8 @@ private:
HTTPSConnection* connectionFromReplyWithState(QNetworkReply* reply); HTTPSConnection* connectionFromReplyWithState(QNetworkReply* reply);
void readPendingContent(HTTPConnection* connection, QString filename);
bool forwardMetaverseAPIRequest(HTTPConnection* connection, bool forwardMetaverseAPIRequest(HTTPConnection* connection,
const QString& metaversePath, const QString& metaversePath,
const QString& requestSubobject, const QString& requestSubobject,