Created RequestModule

This commit is contained in:
CFresquet 2017-05-01 08:07:16 -07:00
parent c518aa55be
commit 28aaa545d8
3 changed files with 105 additions and 112 deletions

View file

@ -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,

View file

@ -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="([^"]*)"/);

87
scripts/system/request.js Normal file
View file

@ -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(' '));
}