src/net/xhr.js
define(function (require) {
"use strict";
var convert = require("net/convert");
var unsafeHeaders = ["ACCEPT-CHARSET", "ACCEPT-ENCODING", "ACCESS-CONTROL-REQUEST-HEADERS",
"ACCESS-CONTROL-REQUEST-METHOD", "CONNECTION", "CONTENT-LENGTH", "CONTENT-TRANSFER-ENCODING", "COOKIE",
"COOKIE2", "DATE", "EXPECT", "HOST", "KEEP-ALIVE", "ORIGIN", "REFERER", "TE", "TRAILER", "TRANSFER-ENCODING",
"UPGRADE", "USER-AGENT", "VIA"];
function http() {
var that = {};
/**
* Make an asynchronous HTTP GET request.
*
* @param {string} url Destination URL
* @param {object|function} [options]
* @param {function} [callback]
*/
that.get = function (url, options, callback) {
httpRequest("GET", url, options, callback);
};
/**
* Make an asynchronous HTTP POST request.
*
* @param {string} url Destination URL
* @param {object|function} [options]
* @param {function} [callback]
*/
that.post = function (url, options, callback) {
httpRequest("POST", url, options, callback);
};
return that;
}
function soap() {
var that = {};
/**
* Make a asynchronous SOAP request.
*
* @param {object} soapMessage SOAP message
* @param {function} [callback] Success callback
*/
that.request = function (ip, port, soapMessage, callback) {
var url = "http://" + ip + ":" + port + soapMessage.serviceUri;
var options = {
body: convert.toUint8Array(soapMessage.body),
requestHeaders: []
};
options.requestHeaders.push({key: "CONTENT-TYPE", value: "text/xml; charset=\"utf-8\""});
options.requestHeaders.push({key: "SOAPACTION", value: soapMessage.headers.getHeaderValue("SOAPACTION")});
httpRequest("POST", url, options, callback);
};
return that;
}
/**
* Private method for building the XHR request. This is done the same way for both SOAP and regular HTTP
* requests.
*
* @param {string} action
* @param {string} url
* @param {object} options
* @param {function} callback
*/
function httpRequest(action, url, options, callback) {
callback = typeof arguments[2] === "function" ? arguments[2] : arguments[3];
options = typeof arguments[2] === "object" ? arguments[2] : {};
var requestHeaders = options.requestHeaders || [];
var responseType = options.responseType || "text";
var body = options.body || undefined;
var xhr = new XMLHttpRequest();
xhr.open(action, url, true);
setSafeRequestHeaders(xhr, requestHeaders);
xhr.responseType = responseType;
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
if (typeof callback === "function") {
console.debug("Got HTTP 200 response on request: %s", url);
var responseContent = xhr[getXhrResponseProperty(responseType)];
callback(responseContent);
}
}
else if (xhr.status !== 200) {
console.warn("Got status code 'HTTP %d' from %s", xhr.status, url);
}
};
console.debug("Making XHR request: %s", url);
xhr.send(body);
}
function getXhrResponseProperty(responseType) {
return responseType === "text" ? "responseText" : "response";
}
/**
* Filter out headers that can not be set by XHR request
*
* @param {XMLHttpRequest} xhr
* @param {object[]} requestHeaders
*/
function setSafeRequestHeaders(xhr, requestHeaders) {
requestHeaders.forEach(function (requestHeader) {
if (unsafeHeaders.indexOf(requestHeader.key) < 0) {
xhr.setRequestHeader(requestHeader.key, requestHeader.value);
}
});
}
return {
http: http,
soap: soap
};
}
);