From 28aaa545d84909cb44755c027ed9ddb4d0f80f8a Mon Sep 17 00:00:00 2001 From: CFresquet Date: Mon, 1 May 2017 08:07:16 -0700 Subject: [PATCH 1/5] Created RequestModule --- scripts/system/makeUserConnection.js | 69 ++++------------------ scripts/system/pal.js | 61 +++---------------- scripts/system/request.js | 87 ++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 112 deletions(-) create mode 100644 scripts/system/request.js diff --git a/scripts/system/makeUserConnection.js b/scripts/system/makeUserConnection.js index 0ffea0c568..56eaf34a6d 100644 --- a/scripts/system/makeUserConnection.js +++ b/scripts/system/makeUserConnection.js @@ -9,6 +9,9 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // + +var RequestModule = Script.require('./request.js'); + (function() { // BEGIN LOCAL_SCOPE var LABEL = "makeUserConnection"; @@ -121,64 +124,13 @@ [].map.call(arguments, JSON.stringify))); } + function debugPrint() { + print( [].slice.call(arguments).join(' ') ); + } + function cleanId(guidWithCurlyBraces) { return guidWithCurlyBraces.slice(1, -1); } - function request(options, callback) { // cb(error, responseOfCorrectContentType) of url. A subset of npm request. - var httpRequest = new XMLHttpRequest(), key; - // QT bug: apparently doesn't handle onload. Workaround using readyState. - httpRequest.onreadystatechange = function () { - var READY_STATE_DONE = 4; - var HTTP_OK = 200; - if (httpRequest.readyState >= READY_STATE_DONE) { - var error = (httpRequest.status !== HTTP_OK) && httpRequest.status.toString() + ':' + httpRequest.statusText, - response = !error && httpRequest.responseText, - contentType = !error && httpRequest.getResponseHeader('content-type'); - if (!error && contentType.indexOf('application/json') === 0) { // ignoring charset, etc. - try { - response = JSON.parse(response); - } catch (e) { - error = e; - } - } - if (error) { - response = {statusCode: httpRequest.status}; - } - callback(error, response); - } - }; - if (typeof options === 'string') { - options = {uri: options}; - } - if (options.url) { - options.uri = options.url; - } - if (!options.method) { - options.method = 'GET'; - } - if (options.body && (options.method === 'GET')) { // add query parameters - var params = [], appender = (-1 === options.uri.search('?')) ? '?' : '&'; - for (key in options.body) { - if (options.body.hasOwnProperty(key)) { - params.push(key + '=' + options.body[key]); - } - } - options.uri += appender + params.join('&'); - delete options.body; - } - if (options.json) { - options.headers = options.headers || {}; - options.headers["Content-type"] = "application/json"; - options.body = JSON.stringify(options.body); - } - for (key in options.headers || {}) { - if (options.headers.hasOwnProperty(key)) { - httpRequest.setRequestHeader(key, options.headers[key]); - } - } - httpRequest.open(options.method, options.uri, true); - httpRequest.send(options.body); - } function handToString(hand) { if (hand === Controller.Standard.RightHand) { @@ -420,6 +372,7 @@ // initiate the shake, they will race to see who sends the connectionRequest after noticing the // waiting message. Either way, they will start connecting eachother at that point. function startHandshake(fromKeyboard) { + if (fromKeyboard) { debug("adding animation"); // just in case order of press/unpress is broken @@ -492,7 +445,7 @@ } // No-op if we were successful, but this way we ensure that failures and abandoned handshakes don't leave us // in a weird state. - request({uri: requestUrl, method: 'DELETE'}, debug); + RequestModule.request({ uri: requestUrl, method: 'DELETE' }, debug); } function updateTriggers(value, fromKeyboard, hand) { @@ -606,7 +559,7 @@ connectionRequestCompleted(); } else { // poll Script.setTimeout(function () { - request({ + RequestModule.request({ uri: requestUrl, // N.B.: server gives bad request if we specify json content type, so don't do that. body: requestBody @@ -658,7 +611,7 @@ // This will immediately set response if successful (e.g., the other guy got his request in first), // or immediate failure, and will otherwise poll (using the requestBody we just set). - request({ // + RequestModule.request({ // uri: requestUrl, method: 'POST', json: true, diff --git a/scripts/system/pal.js b/scripts/system/pal.js index ae64065216..c543926fb3 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -12,6 +12,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +var RequestModule = Script.require('./request.js'); + (function() { // BEGIN LOCAL_SCOPE var populateNearbyUserList, color, textures, removeOverlays, @@ -271,7 +273,7 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See break; case 'removeConnection': connectionUserName = message.params; - request({ + RequestModule.request({ uri: METAVERSE_BASE + '/api/v1/user/connections/' + connectionUserName, method: 'DELETE' }, function (error, response) { @@ -285,7 +287,7 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See case 'removeFriend': friendUserName = message.params; - request({ + RequestModule.request({ uri: METAVERSE_BASE + '/api/v1/user/friends/' + friendUserName, method: 'DELETE' }, function (error, response) { @@ -298,7 +300,7 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See break case 'addFriend': friendUserName = message.params; - request({ + RequestModule.request({ uri: METAVERSE_BASE + '/api/v1/user/friends', method: 'POST', json: true, @@ -331,58 +333,9 @@ function updateUser(data) { // // These are prototype versions that will be changed when the back end changes. var METAVERSE_BASE = location.metaverseServerUrl; -function request(options, callback) { // cb(error, responseOfCorrectContentType) of url. A subset of npm request. - var httpRequest = new XMLHttpRequest(), key; - // QT bug: apparently doesn't handle onload. Workaround using readyState. - httpRequest.onreadystatechange = function () { - var READY_STATE_DONE = 4; - var HTTP_OK = 200; - if (httpRequest.readyState >= READY_STATE_DONE) { - var error = (httpRequest.status !== HTTP_OK) && httpRequest.status.toString() + ':' + httpRequest.statusText, - response = !error && httpRequest.responseText, - contentType = !error && httpRequest.getResponseHeader('content-type'); - if (!error && contentType.indexOf('application/json') === 0) { // ignoring charset, etc. - try { - response = JSON.parse(response); - } catch (e) { - error = e; - } - } - callback(error, response); - } - }; - if (typeof options === 'string') { - options = {uri: options}; - } - if (options.url) { - options.uri = options.url; - } - if (!options.method) { - options.method = 'GET'; - } - if (options.body && (options.method === 'GET')) { // add query parameters - var params = [], appender = (-1 === options.uri.search('?')) ? '?' : '&'; - for (key in options.body) { - params.push(key + '=' + options.body[key]); - } - options.uri += appender + params.join('&'); - delete options.body; - } - if (options.json) { - options.headers = options.headers || {}; - options.headers["Content-type"] = "application/json"; - options.body = JSON.stringify(options.body); - } - for (key in options.headers || {}) { - httpRequest.setRequestHeader(key, options.headers[key]); - } - httpRequest.open(options.method, options.uri, true); - httpRequest.send(options.body); -} - function requestJSON(url, callback) { // callback(data) if successfull. Logs otherwise. - request({ + RequestModule.request({ uri: url }, function (error, response) { if (error || (response.status !== 'success')) { @@ -394,7 +347,7 @@ function requestJSON(url, callback) { // callback(data) if successfull. Logs oth } function getProfilePicture(username, callback) { // callback(url) if successfull. (Logs otherwise) // FIXME Prototype scrapes profile picture. We should include in user status, and also make available somewhere for myself - request({ + RequestModule.request({ uri: METAVERSE_BASE + '/users/' + username }, function (error, html) { var matched = !error && html.match(/img class="users-img" src="([^"]*)"/); diff --git a/scripts/system/request.js b/scripts/system/request.js new file mode 100644 index 0000000000..a5c419892e --- /dev/null +++ b/scripts/system/request.js @@ -0,0 +1,87 @@ +"use strict"; + +// request.js +// +// Created by Cisco Fresquet on 04/24/2017. +// Copyright 2017 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 +// + +/* global module */ +// @module request +// +// This module contains the `request` module implementation + +// =========================================================================================== +module.exports = { + + // ------------------------------------------------------------------ + test: function () { + debug("Test completed."); + }, + + // ------------------------------------------------------------------ + request: function (options, callback) { // cb(error, responseOfCorrectContentType) of url. A subset of npm request. + var httpRequest = new XMLHttpRequest(), key; + // QT bug: apparently doesn't handle onload. Workaround using readyState. + httpRequest.onreadystatechange = function () { + var READY_STATE_DONE = 4; + var HTTP_OK = 200; + if (httpRequest.readyState >= READY_STATE_DONE) { + var error = (httpRequest.status !== HTTP_OK) && httpRequest.status.toString() + ':' + httpRequest.statusText, + response = !error && httpRequest.responseText, + contentType = !error && httpRequest.getResponseHeader('content-type'); + if (!error && contentType.indexOf('application/json') === 0) { // ignoring charset, etc. + try { + response = JSON.parse(response); + } catch (e) { + error = e; + } + } + if (error) { + response = { statusCode: httpRequest.status }; + } + callback(error, response); + } + }; + if (typeof options === 'string') { + options = { uri: options }; + } + if (options.url) { + options.uri = options.url; + } + if (!options.method) { + options.method = 'GET'; + } + if (options.body && (options.method === 'GET')) { // add query parameters + var params = [], appender = (-1 === options.uri.search('?')) ? '?' : '&'; + for (key in options.body) { + if (options.body.hasOwnProperty(key)) { + params.push(key + '=' + options.body[key]); + } + } + options.uri += appender + params.join('&'); + delete options.body; + } + if (options.json) { + options.headers = options.headers || {}; + options.headers["Content-type"] = "application/json"; + options.body = JSON.stringify(options.body); + } + for (key in options.headers || {}) { + if (options.headers.hasOwnProperty(key)) { + httpRequest.setRequestHeader(key, options.headers[key]); + } + } + httpRequest.open(options.method, options.uri, true); + httpRequest.send(options.body); + } +}; + +// =========================================================================================== +// @function - debug logging +function debug() { + print('RequestModule | ' + [].slice.call(arguments).join(' ')); +} From 15db80c8ba7420aff0eb2f9c51c6fdc86455bf33 Mon Sep 17 00:00:00 2001 From: CFresquet Date: Wed, 3 May 2017 07:32:23 -0700 Subject: [PATCH 2/5] request module updates --- scripts/modules/request.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/scripts/modules/request.js b/scripts/modules/request.js index a5c419892e..c7bf98d815 100644 --- a/scripts/modules/request.js +++ b/scripts/modules/request.js @@ -17,11 +17,6 @@ // =========================================================================================== module.exports = { - // ------------------------------------------------------------------ - test: function () { - debug("Test completed."); - }, - // ------------------------------------------------------------------ request: function (options, callback) { // cb(error, responseOfCorrectContentType) of url. A subset of npm request. var httpRequest = new XMLHttpRequest(), key; From b54ea63af7dfbe082afd3dd550dd2d95ed978658 Mon Sep 17 00:00:00 2001 From: CFresquet Date: Wed, 3 May 2017 07:35:30 -0700 Subject: [PATCH 3/5] incremental request module fixes --- scripts/system/makeUserConnection.js | 3 +- scripts/system/pal.js | 3 +- scripts/system/tablet-goto.js | 54 ++++------------------------ 3 files changed, 10 insertions(+), 50 deletions(-) diff --git a/scripts/system/makeUserConnection.js b/scripts/system/makeUserConnection.js index 4426ce5c24..beee766d5c 100644 --- a/scripts/system/makeUserConnection.js +++ b/scripts/system/makeUserConnection.js @@ -14,7 +14,8 @@ (function() { // BEGIN LOCAL_SCOPE - var request = Script.require('../modules/request.js').request; + var REQUEST_URL = Script.resolvePath('request.js'); + var request = Script.require(REQUEST_URL).request; var LABEL = "makeUserConnection"; var MAX_AVATAR_DISTANCE = 0.2; // m diff --git a/scripts/system/pal.js b/scripts/system/pal.js index ffde058cfc..d81946562b 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -14,7 +14,8 @@ (function() { // BEGIN LOCAL_SCOPE - var request = Script.require('../modules/request.js').request; + var REQUEST_URL = Script.resolvePath('request.js'); + var request = Script.require(REQUEST_URL).request; var populateNearbyUserList, color, textures, removeOverlays, controllerComputePickRay, onTabletButtonClicked, onTabletScreenChanged, diff --git a/scripts/system/tablet-goto.js b/scripts/system/tablet-goto.js index fec7a6de90..68706ffb68 100644 --- a/scripts/system/tablet-goto.js +++ b/scripts/system/tablet-goto.js @@ -14,6 +14,10 @@ // (function () { // BEGIN LOCAL_SCOPE + + var REQUEST_URL = Script.resolvePath('request.js'); + var request = Script.require(REQUEST_URL).request; + var gotoQmlSource = "TabletAddressDialog.qml"; var buttonName = "GOTO"; var onGotoScreen = false; @@ -30,54 +34,7 @@ text: buttonName, sortOrder: 8 }); - function request(options, callback) { // cb(error, responseOfCorrectContentType) of url. A subset of npm request. - var httpRequest = new XMLHttpRequest(), key; - // QT bug: apparently doesn't handle onload. Workaround using readyState. - httpRequest.onreadystatechange = function () { - var READY_STATE_DONE = 4; - var HTTP_OK = 200; - if (httpRequest.readyState >= READY_STATE_DONE) { - var error = (httpRequest.status !== HTTP_OK) && httpRequest.status.toString() + ':' + httpRequest.statusText, - response = !error && httpRequest.responseText, - contentType = !error && httpRequest.getResponseHeader('content-type'); - if (!error && contentType.indexOf('application/json') === 0) { // ignoring charset, etc. - try { - response = JSON.parse(response); - } catch (e) { - error = e; - } - } - callback(error, response); - } - }; - if (typeof options === 'string') { - options = {uri: options}; - } - if (options.url) { - options.uri = options.url; - } - if (!options.method) { - options.method = 'GET'; - } - if (options.body && (options.method === 'GET')) { // add query parameters - var params = [], appender = (-1 === options.uri.search('?')) ? '?' : '&'; - for (key in options.body) { - params.push(key + '=' + options.body[key]); - } - options.uri += appender + params.join('&'); - delete options.body; - } - if (options.json) { - options.headers = options.headers || {}; - options.headers["Content-type"] = "application/json"; - options.body = JSON.stringify(options.body); - } - for (key in options.headers || {}) { - httpRequest.setRequestHeader(key, options.headers[key]); - } - httpRequest.open(options.method, options.uri, true); - httpRequest.send(options.body); - } + function fromQml(message) { var response = {id: message.id, jsonrpc: "2.0"}; switch (message.method) { @@ -99,6 +56,7 @@ // No need for a different activeIcon, because we issue messagesWaiting(false) when the button goes active anyway. }); } + var hasEventBridge = false; function wireEventBridge(on) { if (on) { From 28b166c51fd74201502a1af0622795817bd95331 Mon Sep 17 00:00:00 2001 From: CFresquet Date: Wed, 3 May 2017 07:51:49 -0700 Subject: [PATCH 4/5] further request fiddling --- scripts/system/makeUserConnection.js | 3 +-- scripts/system/pal.js | 3 +-- scripts/system/tablet-goto.js | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/scripts/system/makeUserConnection.js b/scripts/system/makeUserConnection.js index beee766d5c..34100806b5 100644 --- a/scripts/system/makeUserConnection.js +++ b/scripts/system/makeUserConnection.js @@ -14,8 +14,7 @@ (function() { // BEGIN LOCAL_SCOPE - var REQUEST_URL = Script.resolvePath('request.js'); - var request = Script.require(REQUEST_URL).request; + var request = Script.require('request').request; var LABEL = "makeUserConnection"; var MAX_AVATAR_DISTANCE = 0.2; // m diff --git a/scripts/system/pal.js b/scripts/system/pal.js index d81946562b..9229ec772a 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -14,8 +14,7 @@ (function() { // BEGIN LOCAL_SCOPE - var REQUEST_URL = Script.resolvePath('request.js'); - var request = Script.require(REQUEST_URL).request; + var request = Script.require('request').request; var populateNearbyUserList, color, textures, removeOverlays, controllerComputePickRay, onTabletButtonClicked, onTabletScreenChanged, diff --git a/scripts/system/tablet-goto.js b/scripts/system/tablet-goto.js index 68706ffb68..4e023f5460 100644 --- a/scripts/system/tablet-goto.js +++ b/scripts/system/tablet-goto.js @@ -15,8 +15,7 @@ (function () { // BEGIN LOCAL_SCOPE - var REQUEST_URL = Script.resolvePath('request.js'); - var request = Script.require(REQUEST_URL).request; + var request = Script.require('request').request; var gotoQmlSource = "TabletAddressDialog.qml"; var buttonName = "GOTO"; From afa72210e0bb594700323393d5d0d8ddf9d3f8d8 Mon Sep 17 00:00:00 2001 From: CFresquet Date: Wed, 3 May 2017 10:28:44 -0700 Subject: [PATCH 5/5] requested tweaks to makeUserConnection.js --- scripts/system/makeUserConnection.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/system/makeUserConnection.js b/scripts/system/makeUserConnection.js index 34100806b5..60e289d2cf 100644 --- a/scripts/system/makeUserConnection.js +++ b/scripts/system/makeUserConnection.js @@ -12,7 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -(function() { // BEGIN LOCAL_SCOPE +(function () { // BEGIN LOCAL_SCOPE var request = Script.require('request').request; @@ -126,10 +126,6 @@ [].map.call(arguments, JSON.stringify))); } - function debugPrint() { - print( [].slice.call(arguments).join(' ') ); - } - function cleanId(guidWithCurlyBraces) { return guidWithCurlyBraces.slice(1, -1); }