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;
}
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)
{
if (offset == undefined) {
offset = 0;
}
var fileSize = file.size;
var filename = file.name;
var CHUNK_SIZE = 65536;
if (offset == undefined) {
offset = 0;
}
var isFinal = fileSize - offset > CHUNK_SIZE ? false : true;
var isFinal = Boolean(fileSize - offset <= CHUNK_SIZE);
var nextChunkSize = Math.min(fileSize - offset, CHUNK_SIZE);
var chunk = file.slice(offset, offset + CHUNK_SIZE, file.type);
var chunkFormData = new FormData();
@ -127,38 +104,10 @@ $(document).ready(function(){
function() {
var files = $('#' + RESTORE_SETTINGS_FILE_ID).prop('files');
var fileFormData = new FormData();
fileFormData.append('restore-file', files[0]);
showSpinnerAlert("Uploading content to restore");
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
connection->respond(HTTPConnection::StatusCode200);
} 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);
readPendingContent(connection, uploadedFilename);
} 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));
_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 {
connection->respond(HTTPConnection::StatusCode400);
}
readPendingContent(connection, uploadedFilename);
} else {
// we don't have handling for this filetype, send back a 400 for failure
connection->respond(HTTPConnection::StatusCode400);
}
} else {
// respond with a 400 for failure
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) {
// grab the UUID state property from the reply
QUuid stateUUID = reply->property(STATE_QUERY_KEY.toLocal8Bit()).toUuid();

View file

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