From 0a55bcb0c55203527e808de2d2179c5731e498d8 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 31 Mar 2015 16:56:04 -0700 Subject: [PATCH 1/2] Remove XMLHttpRequest's facility to read local files --- .../script-engine/src/XMLHttpRequestClass.cpp | 160 +++--------------- .../script-engine/src/XMLHttpRequestClass.h | 2 - 2 files changed, 27 insertions(+), 135 deletions(-) diff --git a/libraries/script-engine/src/XMLHttpRequestClass.cpp b/libraries/script-engine/src/XMLHttpRequestClass.cpp index 3054472a3c..75f51d1cdf 100644 --- a/libraries/script-engine/src/XMLHttpRequestClass.cpp +++ b/libraries/script-engine/src/XMLHttpRequestClass.cpp @@ -13,14 +13,13 @@ // #include -#include #include +#include #include -#include -#include "XMLHttpRequestClass.h" #include "ScriptEngine.h" +#include "XMLHttpRequestClass.h" const QString METAVERSE_API_URL = "https://metaverse.highfidelity.com/api/"; @@ -41,7 +40,6 @@ XMLHttpRequestClass::XMLHttpRequestClass(QScriptEngine* engine) : _onReadyStateChange(QScriptValue::NullValue), _readyState(XMLHttpRequestClass::UNSENT), _errorCode(QNetworkReply::NoError), - _file(NULL), _timeout(0), _timer(this), _numRedirects(0) { @@ -62,22 +60,6 @@ QScriptValue XMLHttpRequestClass::getStatus() const { if (_reply) { return QScriptValue(_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt()); } - if(_url.isLocalFile()) { - switch (_errorCode) { - case QNetworkReply::NoError: - return QScriptValue(200); - case QNetworkReply::ContentNotFoundError: - return QScriptValue(404); - case QNetworkReply::ContentConflictError: - return QScriptValue(409); - case QNetworkReply::TimeoutError: - return QScriptValue(408); - case QNetworkReply::ContentOperationNotPermittedError: - return QScriptValue(501); - default: - break; - } - } return QScriptValue(0); } @@ -85,22 +67,6 @@ QString XMLHttpRequestClass::getStatusText() const { if (_reply) { return _reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(); } - if (_url.isLocalFile()) { - switch (_errorCode) { - case QNetworkReply::NoError: - return "OK"; - case QNetworkReply::ContentNotFoundError: - return "Not Found"; - case QNetworkReply::ContentConflictError: - return "Conflict"; - case QNetworkReply::TimeoutError: - return "Timeout"; - case QNetworkReply::ContentOperationNotPermittedError: - return "Not Implemented"; - default: - break; - } - } return ""; } @@ -146,13 +112,6 @@ QScriptValue XMLHttpRequestClass::getAllResponseHeaders() const { } return QString(headers.data()); } - if (_url.isLocalFile()) { - QString headers = QString("Content-Type: application/octet-stream\n"); - headers.append("Content-Length: "); - headers.append(QString("%1").arg(_rawResponseData.length())); - headers.append("\n"); - return headers; - } return QScriptValue(""); } @@ -160,14 +119,6 @@ QScriptValue XMLHttpRequestClass::getResponseHeader(const QString& name) const { if (_reply && _reply->hasRawHeader(name.toLatin1())) { return QScriptValue(QString(_reply->rawHeader(name.toLatin1()))); } - if (_url.isLocalFile()) { - if (name.toLower() == "content-type") { - return QString("application/octet-stream"); - } - if (name.toLower() == "content-length") { - return QString("%1").arg(_rawResponseData.length()); - } - } return QScriptValue::NullValue; } @@ -187,47 +138,24 @@ void XMLHttpRequestClass::open(const QString& method, const QString& url, bool a _url.setUrl(url); _async = async; - if (_url.isLocalFile()) { - if (_method.toUpper() == "GET" && !_async && username.isEmpty() && password.isEmpty()) { - _file = new QFile(_url.toLocalFile()); - if (!_file->exists()) { - qDebug() << "Can't find file " << _url.fileName(); - abortRequest(); - _errorCode = QNetworkReply::ContentNotFoundError; - setReadyState(DONE); - emit requestComplete(); - } else if (!_file->open(QIODevice::ReadOnly)) { - qDebug() << "Can't open file " << _url.fileName(); - abortRequest(); - _errorCode = QNetworkReply::ContentConflictError; - setReadyState(DONE); - emit requestComplete(); - } else { - setReadyState(OPENED); - } - } else { - notImplemented(); - } - } else { - if (url.toLower().left(METAVERSE_API_URL.length()) == METAVERSE_API_URL) { - AccountManager& accountManager = AccountManager::getInstance(); + if (url.toLower().left(METAVERSE_API_URL.length()) == METAVERSE_API_URL) { + AccountManager& accountManager = AccountManager::getInstance(); - if (accountManager.hasValidAccessToken()) { - QUrlQuery urlQuery(_url.query()); - urlQuery.addQueryItem("access_token", accountManager.getAccountInfo().getAccessToken().token); - _url.setQuery(urlQuery); - } + if (accountManager.hasValidAccessToken()) { + QUrlQuery urlQuery(_url.query()); + urlQuery.addQueryItem("access_token", accountManager.getAccountInfo().getAccessToken().token); + _url.setQuery(urlQuery); + } - } - if (!username.isEmpty()) { - _url.setUserName(username); - } - if (!password.isEmpty()) { - _url.setPassword(password); - } - _request.setUrl(_url); - setReadyState(OPENED); } + if (!username.isEmpty()) { + _url.setUserName(username); + } + if (!password.isEmpty()) { + _url.setPassword(password); + } + _request.setUrl(_url); + setReadyState(OPENED); } } @@ -238,23 +166,18 @@ void XMLHttpRequestClass::send() { void XMLHttpRequestClass::send(const QScriptValue& data) { if (_readyState == OPENED && !_reply) { if (!data.isNull()) { - if (_url.isLocalFile()) { - notImplemented(); - return; + _sendData = new QBuffer(this); + if (data.isObject()) { + QByteArray ba = qscriptvalue_cast(data); + _sendData->setData(ba); } else { - _sendData = new QBuffer(this); - if (data.isObject()) { - QByteArray ba = qscriptvalue_cast(data); - _sendData->setData(ba); - } else { - _sendData->setData(data.toString().toUtf8()); - } + _sendData->setData(data.toString().toUtf8()); } } doSend(); - if (!_async && !_url.isLocalFile()) { + if (!_async) { QEventLoop loop; connect(this, SIGNAL(requestComplete()), &loop, SLOT(quit())); loop.exec(); @@ -264,23 +187,13 @@ void XMLHttpRequestClass::send(const QScriptValue& data) { void XMLHttpRequestClass::doSend() { - if (!_url.isLocalFile()) { - _reply = NetworkAccessManager::getInstance().sendCustomRequest(_request, _method.toLatin1(), _sendData); - connectToReply(_reply); - } + _reply = NetworkAccessManager::getInstance().sendCustomRequest(_request, _method.toLatin1(), _sendData); + connectToReply(_reply); if (_timeout > 0) { _timer.start(_timeout); connect(&_timer, SIGNAL(timeout()), this, SLOT(requestTimeout())); } - - if (_url.isLocalFile()) { - setReadyState(HEADERS_RECEIVED); - setReadyState(LOADING); - _rawResponseData = _file->readAll(); - _file->close(); - requestFinished(); - } } void XMLHttpRequestClass::requestTimeout() { @@ -299,16 +212,10 @@ void XMLHttpRequestClass::requestError(QNetworkReply::NetworkError code) { void XMLHttpRequestClass::requestFinished() { disconnect(&_timer, SIGNAL(timeout()), this, SLOT(requestTimeout())); - if (!_url.isLocalFile()) { - _errorCode = _reply->error(); - } else { - _errorCode = QNetworkReply::NoError; - } + _errorCode = _reply->error(); if (_errorCode == QNetworkReply::NoError) { - if (!_url.isLocalFile()) { - _rawResponseData.append(_reply->readAll()); - } + _rawResponseData.append(_reply->readAll()); if (_responseType == "json") { _responseData = _engine->evaluate("(" + QString(_rawResponseData.data()) + ")"); @@ -337,19 +244,6 @@ void XMLHttpRequestClass::abortRequest() { _reply->deleteLater(); _reply = NULL; } - - if (_file != NULL) { - _file->close(); - _file = NULL; - } -} - -void XMLHttpRequestClass::notImplemented() { - abortRequest(); - //_errorCode = QNetworkReply::OperationNotImplementedError; TODO: Use this status code when update to Qt 5.3 - _errorCode = QNetworkReply::ContentOperationNotPermittedError; - setReadyState(DONE); - emit requestComplete(); } void XMLHttpRequestClass::connectToReply(QNetworkReply* reply) { diff --git a/libraries/script-engine/src/XMLHttpRequestClass.h b/libraries/script-engine/src/XMLHttpRequestClass.h index 55bf646476..c79859e895 100644 --- a/libraries/script-engine/src/XMLHttpRequestClass.h +++ b/libraries/script-engine/src/XMLHttpRequestClass.h @@ -97,7 +97,6 @@ private: void connectToReply(QNetworkReply* reply); void disconnectFromReply(QNetworkReply* reply); void abortRequest(); - void notImplemented(); QScriptEngine* _engine; bool _async; @@ -113,7 +112,6 @@ private: QScriptValue _onReadyStateChange; ReadyState _readyState; QNetworkReply::NetworkError _errorCode; - QFile* _file; int _timeout; QTimer _timer; int _numRedirects; From edaa4cdc65da85d47b5a4d3c9106950ba43e92df Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 31 Mar 2015 16:57:15 -0700 Subject: [PATCH 2/2] Remove local file reading from scripts --- examples/edit.js | 2 - examples/libraries/modelUploader.js | 693 ------------------ .../utilities/diagnostics/XMLHttpRequest.js | 95 --- 3 files changed, 790 deletions(-) delete mode 100644 examples/libraries/modelUploader.js diff --git a/examples/edit.js b/examples/edit.js index 08a2c4f3f7..156cf44fa0 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -16,8 +16,6 @@ HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; Script.include([ "libraries/stringHelpers.js", "libraries/dataviewHelpers.js", - "libraries/httpMultiPart.js", - "libraries/modelUploader.js", "libraries/toolBars.js", "libraries/progressDialog.js", diff --git a/examples/libraries/modelUploader.js b/examples/libraries/modelUploader.js deleted file mode 100644 index 64a9e91203..0000000000 --- a/examples/libraries/modelUploader.js +++ /dev/null @@ -1,693 +0,0 @@ -// -// modelUploader.js -// examples/libraries -// -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - - -modelUploader = (function () { - var that = {}, - modelFile, - modelName, - modelURL, - modelCallback, - isProcessing, - fstBuffer, - fbxBuffer, - //svoBuffer, - mapping, - geometry, - API_URL = "https://metaverse.highfidelity.com/api/v1/models", - MODEL_URL = "http://public.highfidelity.com/models/content", - NAME_FIELD = "name", - SCALE_FIELD = "scale", - FILENAME_FIELD = "filename", - TEXDIR_FIELD = "texdir", - MAX_TEXTURE_SIZE = 1024; - - function info(message) { - if (progressDialog.isOpen()) { - progressDialog.update(message); - } else { - progressDialog.open(message); - } - print(message); - } - - function error(message) { - if (progressDialog.isOpen()) { - progressDialog.close(); - } - print(message); - Window.alert(message); - } - - function randomChar(length) { - var characters = "0123457689abcdefghijklmnopqrstuvwxyz", - string = "", - i; - - for (i = 0; i < length; i += 1) { - string += characters[Math.floor(Math.random() * 36)]; - } - - return string; - } - - function resetDataObjects() { - fstBuffer = null; - fbxBuffer = null; - //svoBuffer = null; - mapping = {}; - geometry = {}; - geometry.textures = []; - geometry.embedded = []; - } - - function readFile(filename) { - var url = "file:///" + filename, - req = new XMLHttpRequest(); - - req.open("GET", url, false); - req.responseType = "arraybuffer"; - req.send(); - if (req.status !== 200) { - error("Could not read file: " + filename + " : " + req.statusText); - return null; - } - - return { - filename: filename.fileName(), - buffer: req.response - }; - } - - function readMapping(buffer) { - var dv = new DataView(buffer.buffer), - lines, - line, - tokens, - i, - name, - value, - remainder, - existing; - - mapping = {}; // { name : value | name : { value : [remainder] } } - lines = dv.string(0, dv.byteLength).split(/\r\n|\r|\n/); - for (i = 0; i < lines.length; i += 1) { - line = lines[i].trim(); - if (line.length > 0 && line[0] !== "#") { - tokens = line.split(/\s*=\s*/); - if (tokens.length > 1) { - name = tokens[0]; - value = tokens[1]; - if (tokens.length > 2) { - remainder = tokens.slice(2, tokens.length).join(" = "); - } else { - remainder = null; - } - if (tokens.length === 2 && mapping[name] === undefined) { - mapping[name] = value; - } else { - if (mapping[name] === undefined) { - mapping[name] = {}; - - } else if (typeof mapping[name] !== "object") { - existing = mapping[name]; - mapping[name] = { existing : null }; - } - - if (mapping[name][value] === undefined) { - mapping[name][value] = []; - } - mapping[name][value].push(remainder); - } - } - } - } - } - - function writeMapping(buffer) { - var name, - value, - remainder, - i, - string = ""; - - for (name in mapping) { - if (mapping.hasOwnProperty(name)) { - if (typeof mapping[name] === "object") { - for (value in mapping[name]) { - if (mapping[name].hasOwnProperty(value)) { - remainder = mapping[name][value]; - if (remainder === null) { - string += (name + " = " + value + "\n"); - } else { - for (i = 0; i < remainder.length; i += 1) { - string += (name + " = " + value + " = " + remainder[i] + "\n"); - } - } - } - } - } else { - string += (name + " = " + mapping[name] + "\n"); - } - } - } - - buffer.buffer = string.toArrayBuffer(); - } - - function readGeometry(fbxBuffer) { - var textures, - view, - index, - EOF, - previousNodeFilename; - - // Reference: - // http://code.blender.org/index.php/2013/08/fbx-binary-file-format-specification/ - - textures = {}; - view = new DataView(fbxBuffer.buffer); - EOF = false; - - function parseBinaryFBX() { - var endOffset, - numProperties, - propertyListLength, - nameLength, - name, - filename; - - endOffset = view.getUint32(index, true); - numProperties = view.getUint32(index + 4, true); - propertyListLength = view.getUint32(index + 8, true); - nameLength = view.getUint8(index + 12); - index += 13; - - if (endOffset === 0) { - return; - } - if (endOffset < index || endOffset > view.byteLength) { - EOF = true; - return; - } - - name = view.string(index, nameLength).toLowerCase(); - index += nameLength; - - if (name === "content" && previousNodeFilename !== "") { - // Blender 2.71 exporter "embeds" external textures as empty binary blobs so ignore these - if (propertyListLength > 5) { - geometry.embedded.push(previousNodeFilename); - } - } - - if (name === "relativefilename") { - filename = view.string(index + 5, view.getUint32(index + 1, true)).fileName(); - if (!textures.hasOwnProperty(filename)) { - textures[filename] = ""; - geometry.textures.push(filename); - } - previousNodeFilename = filename; - } else { - previousNodeFilename = ""; - } - - index += (propertyListLength); - - while (index < endOffset && !EOF) { - parseBinaryFBX(); - } - } - - function readTextFBX() { - var line, - view, - viewLength, - charCode, - charCodes, - numCharCodes, - filename, - relativeFilename = "", - MAX_CHAR_CODES = 250; - - view = new Uint8Array(fbxBuffer.buffer); - viewLength = view.byteLength; - charCodes = []; - numCharCodes = 0; - - for (index = 0; index < viewLength; index += 1) { - charCode = view[index]; - if (charCode !== 9 && charCode !== 32) { - if (charCode === 10) { // EOL. Can ignore EOF. - line = String.fromCharCode.apply(String, charCodes).toLowerCase(); - // For embedded textures, "Content:" line immediately follows "RelativeFilename:" line. - if (line.slice(0, 8) === "content:" && relativeFilename !== "") { - geometry.embedded.push(relativeFilename); - } - if (line.slice(0, 17) === "relativefilename:") { - filename = line.slice(line.indexOf("\""), line.lastIndexOf("\"") - line.length).fileName(); - if (!textures.hasOwnProperty(filename)) { - textures[filename] = ""; - geometry.textures.push(filename); - } - relativeFilename = filename; - } else { - relativeFilename = ""; - } - charCodes = []; - numCharCodes = 0; - } else { - if (numCharCodes < MAX_CHAR_CODES) { // Only interested in start of line - charCodes.push(charCode); - numCharCodes += 1; - } - } - } - } - } - - - - readTextFBX(); - - - } - - function readModel() { - var fbxFilename, - //svoFilename, - fileType; - - info("Reading model file"); - print("Model file: " + modelFile); - - if (modelFile.toLowerCase().fileType() === "fst") { - fstBuffer = readFile(modelFile); - if (fstBuffer === null) { - return false; - } - readMapping(fstBuffer); - fileType = mapping[FILENAME_FIELD].toLowerCase().fileType(); - if (mapping.hasOwnProperty(FILENAME_FIELD)) { - if (fileType === "fbx") { - fbxFilename = modelFile.path() + "\\" + mapping[FILENAME_FIELD]; - //} else if (fileType === "svo") { - // svoFilename = modelFile.path() + "\\" + mapping[FILENAME_FIELD]; - } else { - error("Unrecognized model type in FST file!"); - return false; - } - } else { - error("Model file name not found in FST file!"); - return false; - } - } else { - fstBuffer = { - filename: "Interface." + randomChar(6), // Simulate avatar model uploading behaviour - buffer: null - }; - - if (modelFile.toLowerCase().fileType() === "fbx") { - fbxFilename = modelFile; - mapping[FILENAME_FIELD] = modelFile.fileName(); - - //} else if (modelFile.toLowerCase().fileType() === "svo") { - // svoFilename = modelFile; - // mapping[FILENAME_FIELD] = modelFile.fileName(); - - } else { - error("Unrecognized file type: " + modelFile); - return false; - } - } - - if (!isProcessing) { return false; } - - if (fbxFilename) { - fbxBuffer = readFile(fbxFilename); - if (fbxBuffer === null) { - return false; - } - - if (!isProcessing) { return false; } - - readGeometry(fbxBuffer); - } - - //if (svoFilename) { - // svoBuffer = readFile(svoFilename); - // if (svoBuffer === null) { - // return false; - // } - //} - - // Add any missing basic mappings - if (!mapping.hasOwnProperty(NAME_FIELD)) { - mapping[NAME_FIELD] = modelFile.fileName().fileBase(); - } - if (!mapping.hasOwnProperty(TEXDIR_FIELD)) { - mapping[TEXDIR_FIELD] = "."; - } - if (!mapping.hasOwnProperty(SCALE_FIELD)) { - mapping[SCALE_FIELD] = 1.0; - } - - return true; - } - - function setProperties() { - var form = [], - directory, - displayAs, - validateAs; - - progressDialog.close(); - print("Setting model properties"); - - form.push({ label: "Name:", value: mapping[NAME_FIELD] }); - - directory = modelFile.path() + "/" + mapping[TEXDIR_FIELD]; - displayAs = new RegExp("^" + modelFile.path().regExpEscape() + "[\\\\\\\/](.*)"); - validateAs = new RegExp("^" + modelFile.path().regExpEscape() + "([\\\\\\\/].*)?"); - - form.push({ - label: "Texture directory:", - directory: modelFile.path() + "/" + mapping[TEXDIR_FIELD], - title: "Choose Texture Directory", - displayAs: displayAs, - validateAs: validateAs, - errorMessage: "Texture directory must be subdirectory of the model directory." - }); - - form.push({ button: "Cancel" }); - - if (!Window.form("Set Model Properties", form)) { - print("User cancelled uploading model"); - return false; - } - - mapping[NAME_FIELD] = form[0].value; - mapping[TEXDIR_FIELD] = form[1].directory.slice(modelFile.path().length + 1); - if (mapping[TEXDIR_FIELD] === "") { - mapping[TEXDIR_FIELD] = "."; - } - - writeMapping(fstBuffer); - - return true; - } - - function createHttpMessage(callback) { - var multiparts = [], - lodCount, - lodFile, - lodBuffer, - textureBuffer, - textureSourceFormat, - textureTargetFormat, - embeddedTextures, - i; - - info("Preparing to send model"); - - // Model name - if (mapping.hasOwnProperty(NAME_FIELD)) { - multiparts.push({ - name : "model_name", - string : mapping[NAME_FIELD] - }); - } else { - error("Model name is missing"); - httpMultiPart.clear(); - return; - } - - // FST file - if (fstBuffer) { - multiparts.push({ - name : "fst", - buffer: fstBuffer - }); - } - - // FBX file - if (fbxBuffer) { - multiparts.push({ - name : "fbx", - buffer: fbxBuffer - }); - } - - // SVO file - //if (svoBuffer) { - // multiparts.push({ - // name : "svo", - // buffer: svoBuffer - // }); - //} - - // LOD files - lodCount = 0; - for (lodFile in mapping.lod) { - if (mapping.lod.hasOwnProperty(lodFile)) { - lodBuffer = readFile(modelFile.path() + "\/" + lodFile); - if (lodBuffer === null) { - return; - } - multiparts.push({ - name: "lod" + lodCount, - buffer: lodBuffer - }); - lodCount += 1; - } - if (!isProcessing) { return; } - } - - // Textures - embeddedTextures = "|" + geometry.embedded.join("|") + "|"; - for (i = 0; i < geometry.textures.length; i += 1) { - if (embeddedTextures.indexOf("|" + geometry.textures[i].fileName() + "|") === -1) { - textureBuffer = readFile(modelFile.path() + "\/" - + (mapping[TEXDIR_FIELD] !== "." ? mapping[TEXDIR_FIELD] + "\/" : "") - + geometry.textures[i]); - if (textureBuffer === null) { - return; - } - - textureSourceFormat = geometry.textures[i].fileType().toLowerCase(); - textureTargetFormat = (textureSourceFormat === "jpg" ? "jpg" : "png"); - textureBuffer.buffer = - textureBuffer.buffer.recodeImage(textureSourceFormat, textureTargetFormat, MAX_TEXTURE_SIZE); - textureBuffer.filename = textureBuffer.filename.slice(0, -textureSourceFormat.length) + textureTargetFormat; - - multiparts.push({ - name: "texture" + i, - buffer: textureBuffer - }); - } - - if (!isProcessing) { return; } - } - - // Model category - multiparts.push({ - name : "model_category", - string : "content" - }); - - // Create HTTP message - httpMultiPart.clear(); - Script.setTimeout(function addMultipart() { - var multipart = multiparts.shift(); - httpMultiPart.add(multipart); - - if (!isProcessing) { return; } - - if (multiparts.length > 0) { - Script.setTimeout(addMultipart, 25); - } else { - callback(); - } - }, 25); - } - - function sendToHighFidelity() { - var req, - uploadedChecks, - HTTP_GET_TIMEOUT = 60, // 1 minute - HTTP_SEND_TIMEOUT = 900, // 15 minutes - UPLOADED_CHECKS = 30, - CHECK_UPLOADED_TIMEOUT = 1, // 1 second - handleCheckUploadedResponses, - handleUploadModelResponses, - handleRequestUploadResponses; - - function uploadTimedOut() { - error("Model upload failed: Internet request timed out!"); - } - - function debugResponse() { - print("req.errorCode = " + req.errorCode); - print("req.readyState = " + req.readyState); - print("req.status = " + req.status); - print("req.statusText = " + req.statusText); - print("req.responseType = " + req.responseType); - print("req.responseText = " + req.responseText); - print("req.response = " + req.response); - print("req.getAllResponseHeaders() = " + req.getAllResponseHeaders()); - } - - function checkUploaded() { - if (!isProcessing) { return; } - - info("Checking uploaded model"); - - req = new XMLHttpRequest(); - req.open("HEAD", modelURL, true); - req.timeout = HTTP_GET_TIMEOUT * 1000; - req.onreadystatechange = handleCheckUploadedResponses; - req.ontimeout = uploadTimedOut; - req.send(); - } - - handleCheckUploadedResponses = function () { - //debugResponse(); - if (req.readyState === req.DONE) { - if (req.status === 200) { - // Note: Unlike avatar models, for content models we don't need to refresh texture cache. - print("Model uploaded: " + modelURL); - progressDialog.close(); - if (Window.confirm("Your model has been uploaded as: " + modelURL + "\nDo you want to rez it?")) { - modelCallback(modelURL); - } - } else if (req.status === 404) { - if (uploadedChecks > 0) { - uploadedChecks -= 1; - Script.setTimeout(checkUploaded, CHECK_UPLOADED_TIMEOUT * 1000); - } else { - print("Error: " + req.status + " " + req.statusText); - error("We could not verify that your model was successfully uploaded but it may have been at: " - + modelURL); - } - } else { - print("Error: " + req.status + " " + req.statusText); - error("There was a problem with your upload, please try again later."); - } - } - }; - - function uploadModel(method) { - var url; - - if (!isProcessing) { return; } - - req = new XMLHttpRequest(); - if (method === "PUT") { - url = API_URL + "\/" + modelName; - req.open("PUT", url, true); //print("PUT " + url); - } else { - url = API_URL; - req.open("POST", url, true); //print("POST " + url); - } - req.setRequestHeader("Content-Type", "multipart/form-data; boundary=\"" + httpMultiPart.boundary() + "\""); - req.timeout = HTTP_SEND_TIMEOUT * 1000; - req.onreadystatechange = handleUploadModelResponses; - req.ontimeout = uploadTimedOut; - req.send(httpMultiPart.response().buffer); - } - - handleUploadModelResponses = function () { - //debugResponse(); - if (req.readyState === req.DONE) { - if (req.status === 200) { - uploadedChecks = UPLOADED_CHECKS; - checkUploaded(); - } else { - print("Error: " + req.status + " " + req.statusText); - error("There was a problem with your upload, please try again later."); - } - } - }; - - function requestUpload() { - var url; - - if (!isProcessing) { return; } - - url = API_URL + "\/" + modelName; // XMLHttpRequest automatically handles authorization of API requests. - req = new XMLHttpRequest(); - req.open("GET", url, true); //print("GET " + url); - req.responseType = "json"; - req.timeout = HTTP_GET_TIMEOUT * 1000; - req.onreadystatechange = handleRequestUploadResponses; - req.ontimeout = uploadTimedOut; - req.send(); - } - - handleRequestUploadResponses = function () { - var response; - - //debugResponse(); - if (req.readyState === req.DONE) { - if (req.status === 200) { - if (req.responseType === "json") { - response = JSON.parse(req.responseText); - if (response.status === "success") { - if (response.exists === false) { - uploadModel("POST"); - } else if (response.can_update === true) { - uploadModel("PUT"); - } else { - error("This model file already exists and is owned by someone else!"); - } - return; - } - } - } else { - print("Error: " + req.status + " " + req.statusText); - } - error("Model upload failed! Something went wrong at the data server."); - } - }; - - info("Sending model to High Fidelity"); - - requestUpload(); - } - - that.upload = function (file, callback) { - - modelFile = file; - modelCallback = callback; - - isProcessing = true; - - progressDialog.onCancel = function () { - print("User cancelled uploading model"); - isProcessing = false; - }; - - resetDataObjects(); - - if (readModel()) { - if (setProperties()) { - modelName = mapping[NAME_FIELD]; - modelURL = MODEL_URL + "\/" + mapping[NAME_FIELD] + ".fst"; // All models are uploaded as an FST - - createHttpMessage(sendToHighFidelity); - } - } - - resetDataObjects(); - }; - - return that; -}()); diff --git a/examples/utilities/diagnostics/XMLHttpRequest.js b/examples/utilities/diagnostics/XMLHttpRequest.js index fb25cb4fad..76374749ac 100644 --- a/examples/utilities/diagnostics/XMLHttpRequest.js +++ b/examples/utilities/diagnostics/XMLHttpRequest.js @@ -145,98 +145,3 @@ test("Test timeout", function() { this.assertEquals(0, req.status, "status should be `0`"); this.assertEquals(4, req.errorCode, "4 is the timeout error code for QNetworkReply::NetworkError"); }); - - -var localFile = Window.browse("Find defaultScripts.js file ...", "", "defaultScripts.js (defaultScripts.js)"); - -if (localFile !== null) { - - localFile = "file:///" + localFile; - - test("Test GET local file synchronously", function () { - var req = new XMLHttpRequest(); - - var statesVisited = [true, false, false, false, false] - req.onreadystatechange = function () { - statesVisited[req.readyState] = true; - }; - - req.open("GET", localFile, false); - req.send(); - - this.assertEquals(req.DONE, req.readyState, "readyState should be DONE"); - this.assertEquals(200, req.status, "status should be `200`"); - this.assertEquals("OK", req.statusText, "statusText should be `OK`"); - this.assertEquals(0, req.errorCode); - this.assertNotEquals("", req.getAllResponseHeaders(), "headers should not be null"); - this.assertContains("High Fidelity", req.response.substring(0, 100), "expected text not found in response") - - for (var i = 0; i <= req.DONE; i++) { - this.assertEquals(true, statesVisited[i], i + " should be set"); - } - }); - - test("Test GET nonexistent local file", function () { - var nonexistentFile = localFile.replace(".js", "NoExist.js"); - - var req = new XMLHttpRequest(); - req.open("GET", nonexistentFile, false); - req.send(); - - this.assertEquals(req.DONE, req.readyState, "readyState should be DONE"); - this.assertEquals(404, req.status, "status should be `404`"); - this.assertEquals("Not Found", req.statusText, "statusText should be `Not Found`"); - this.assertNotEquals(0, req.errorCode); - }); - - test("Test GET local file already open", function () { - // Can't open file exclusively in order to test. - }); - - test("Test GET local file with data not implemented", function () { - var req = new XMLHttpRequest(); - req.open("GET", localFile, true); - req.send("data"); - - this.assertEquals(req.DONE, req.readyState, "readyState should be DONE"); - this.assertEquals(501, req.status, "status should be `501`"); - this.assertEquals("Not Implemented", req.statusText, "statusText should be `Not Implemented`"); - this.assertNotEquals(0, req.errorCode); - }); - - test("Test GET local file asynchronously not implemented", function () { - var req = new XMLHttpRequest(); - req.open("GET", localFile, true); - req.send(); - - this.assertEquals(req.DONE, req.readyState, "readyState should be DONE"); - this.assertEquals(501, req.status, "status should be `501`"); - this.assertEquals("Not Implemented", req.statusText, "statusText should be `Not Implemented`"); - this.assertNotEquals(0, req.errorCode); - }); - - test("Test POST local file not implemented", function () { - var req = new XMLHttpRequest(); - req.open("POST", localFile, false); - req.send(); - - this.assertEquals(req.DONE, req.readyState, "readyState should be DONE"); - this.assertEquals(501, req.status, "status should be `501`"); - this.assertEquals("Not Implemented", req.statusText, "statusText should be `Not Implemented`"); - this.assertNotEquals(0, req.errorCode); - }); - - test("Test local file username and password not implemented", function () { - var req = new XMLHttpRequest(); - req.open("GET", localFile, false, "username", "password"); - req.send(); - - this.assertEquals(req.DONE, req.readyState, "readyState should be DONE"); - this.assertEquals(501, req.status, "status should be `501`"); - this.assertEquals("Not Implemented", req.statusText, "statusText should be `Not Implemented`"); - this.assertNotEquals(0, req.errorCode); - }); - -} else { - print("Local file operation not tested"); -}