Use a random session id for a sequence of chunks

This commit is contained in:
Simon Walton 2018-11-16 15:56:39 -08:00
parent 5883035991
commit 2d2cc0eaca
3 changed files with 23 additions and 16 deletions

View file

@ -10,7 +10,7 @@ $(document).ready(function(){
function progressBarHTML(extraClass, label) {
var html = "<div class='progress'>";
html += "<div class='" + extraClass + " progress-bar progress-bar-success progress-bar-striped active' role='progressbar' aria-valuemin='0' aria-valuemax='100'>";
html += label + "<span class='ongoing-msg'></span></div></div>";
html += "<span class='ongoing-msg'></span></div></div>";
return html;
}
@ -24,10 +24,14 @@ $(document).ready(function(){
});
}
function uploadNextChunk(file, offset) {
function uploadNextChunk(file, offset, id) {
if (offset == undefined) {
offset = 0;
}
if (id == undefined) {
// Identify this upload session
id = Math.round(Math.random() * 2147483647);
}
var fileSize = file.size;
var filename = file.name;
@ -45,6 +49,7 @@ $(document).ready(function(){
url: '/content/upload',
type: 'POST',
timeout: 30000, // 30 s
headers: {"X-Session-Id": id},
cache: false,
processData: false,
contentType: false,
@ -64,7 +69,7 @@ $(document).ready(function(){
if (!isFinal) {
ajaxObject.done(function (data, textStatus, jqXHR)
{ uploadNextChunk(file, offset + CHUNK_SIZE); });
{ uploadNextChunk(file, offset + CHUNK_SIZE, id); });
} else {
ajaxObject.done(function(data, textStatus, jqXHR) {
isRestoring = true;
@ -210,7 +215,7 @@ $(document).ready(function(){
function updateProgressBars($progressBar, value) {
$progressBar.attr('aria-valuenow', value).attr('style', 'width: ' + value + '%');
$progressBar.find('.ongoing-msg').html(" " + Math.round(value) + "% Complete");
$progressBar.find('.ongoing-msg').html(" " + Math.round(value) + "%");
}
function reloadBackupInformation() {

View file

@ -2519,18 +2519,21 @@ bool DomainServer::handleHTTPSRequest(HTTPSConnection* connection, const QUrl &u
}
bool DomainServer::processPendingContent(HTTPConnection* connection, QString itemName, QString filename, QByteArray dataChunk) {
static const QString UPLOAD_SESSION_KEY { "X-Session-Id" };
QByteArray sessionIdBytes = connection->requestHeader(UPLOAD_SESSION_KEY);
int sessionId = sessionIdBytes.toInt();
if (filename.endsWith(".zip", Qt::CaseInsensitive)) {
static const QString TEMPORARY_CONTENT_FILEPATH { QDir::tempPath() + "/hifiUploadContent_XXXXXX.zip" };
const auto peerAddressHash = qHash(connection->socket()->peerAddress());
if (_pendingContentFiles.find(peerAddressHash) == _pendingContentFiles.end()) {
if (_pendingContentFiles.find(sessionId) == _pendingContentFiles.end()) {
std::unique_ptr<QTemporaryFile> newTemp(new QTemporaryFile(TEMPORARY_CONTENT_FILEPATH));
_pendingContentFiles[peerAddressHash] = std::move(newTemp);
_pendingContentFiles[sessionId] = std::move(newTemp);
}
QTemporaryFile& _pendingFileContent = *_pendingContentFiles[peerAddressHash];
QTemporaryFile& _pendingFileContent = *_pendingContentFiles[sessionId];
if (!_pendingFileContent.open()) {
_pendingContentFiles.erase(peerAddressHash);
_pendingContentFiles.erase(sessionId);
connection->respond(HTTPConnection::StatusCode400);
return false;
}
@ -2543,16 +2546,15 @@ bool DomainServer::processPendingContent(HTTPConnection* connection, QString ite
if (itemName == "restore-file-chunk-final" || itemName == "restore-file") {
auto deferred = makePromise("recoverFromUploadedBackup");
deferred->then([this, peerAddressHash](QString error, QVariantMap result) {
_pendingContentFiles.erase(peerAddressHash);
deferred->then([this, sessionId](QString error, QVariantMap result) {
_pendingContentFiles.erase(sessionId);
});
_contentManager->recoverFromUploadedFile(deferred, _pendingFileContent.fileName());
}
} else if (filename.endsWith(".json", Qt::CaseInsensitive)
|| filename.endsWith(".json.gz", Qt::CaseInsensitive)) {
auto peerAddressHash = qHash(connection->socket()->peerAddress());
QByteArray& _pendingUploadedContent = _pendingUploadedContents[peerAddressHash];
QByteArray& _pendingUploadedContent = _pendingUploadedContents[sessionId];
_pendingUploadedContent += dataChunk;
connection->respond(HTTPConnection::StatusCode200);
@ -2560,7 +2562,7 @@ bool DomainServer::processPendingContent(HTTPConnection* connection, QString ite
// invoke our method to hand the new octree file off to the octree server
QMetaObject::invokeMethod(this, "handleOctreeFileReplacement",
Qt::QueuedConnection, Q_ARG(QByteArray, _pendingUploadedContent));
_pendingUploadedContents.erase(peerAddressHash);
_pendingUploadedContents.erase(sessionId);
}
} else {
connection->respond(HTTPConnection::StatusCode400);

View file

@ -284,8 +284,8 @@ private:
QHash<QUuid, QPointer<HTTPSConnection>> _pendingOAuthConnections;
std::unordered_map<uint, QByteArray> _pendingUploadedContents;
std::unordered_map<uint, std::unique_ptr<QTemporaryFile>> _pendingContentFiles;
std::unordered_map<int, QByteArray> _pendingUploadedContents;
std::unordered_map<int, std::unique_ptr<QTemporaryFile>> _pendingContentFiles;
QThread _assetClientThread;
};