Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(http-core): pull in http core in preparation for making local c…
…hanges
- Loading branch information
Ian W. Remmel
committed
Feb 8, 2017
1 parent
432f3ad
commit 8a7d60d
Showing
3 changed files
with
252 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
// Need to fork xhr to support environments with full object freezing; namely, | ||
// SalesForce's Aura and Locker environment. | ||
|
||
// See https://github.com/naugtur/xhr for license information | ||
|
||
// Maintain the original code style of https://github.com/naugtur/xhr since | ||
// we're trying to diverge as little as possible. | ||
/* eslint-disable */ | ||
|
||
"use strict"; | ||
var window = require("global/window") | ||
var isFunction = require("is-function") | ||
var parseHeaders = require("parse-headers") | ||
var xtend = require("xtend") | ||
|
||
module.exports = createXHR | ||
createXHR.XMLHttpRequest = window.XMLHttpRequest || noop | ||
createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest | ||
|
||
forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { | ||
createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { | ||
options = initParams(uri, options, callback) | ||
options.method = method.toUpperCase() | ||
return _createXHR(options) | ||
} | ||
}) | ||
|
||
function forEachArray(array, iterator) { | ||
for (var i = 0; i < array.length; i++) { | ||
iterator(array[i]) | ||
} | ||
} | ||
|
||
function isEmpty(obj){ | ||
for(var i in obj){ | ||
if(obj.hasOwnProperty(i)) return false | ||
} | ||
return true | ||
} | ||
|
||
function initParams(uri, options, callback) { | ||
var params = uri | ||
|
||
if (isFunction(options)) { | ||
callback = options | ||
if (typeof uri === "string") { | ||
params = {uri:uri} | ||
} | ||
} else { | ||
params = xtend(options, {uri: uri}) | ||
} | ||
|
||
params.callback = callback | ||
return params | ||
} | ||
|
||
function createXHR(uri, options, callback) { | ||
options = initParams(uri, options, callback) | ||
return _createXHR(options) | ||
} | ||
|
||
function _createXHR(options) { | ||
if(typeof options.callback === "undefined"){ | ||
throw new Error("callback argument missing") | ||
} | ||
|
||
var called = false | ||
var callback = function cbOnce(err, response, body){ | ||
if(!called){ | ||
called = true | ||
options.callback(err, response, body) | ||
} | ||
} | ||
|
||
function readystatechange() { | ||
if (xhr.readyState === 4) { | ||
setTimeout(loadFunc, 0) | ||
} | ||
} | ||
|
||
function getBody() { | ||
// Chrome with requestType=blob throws errors arround when even testing access to responseText | ||
var body = undefined | ||
|
||
if (xhr.response) { | ||
body = xhr.response | ||
} else { | ||
body = xhr.responseText || getXml(xhr) | ||
} | ||
|
||
if (isJson) { | ||
try { | ||
body = JSON.parse(body) | ||
} catch (e) {} | ||
} | ||
|
||
return body | ||
} | ||
|
||
function errorFunc(evt) { | ||
clearTimeout(timeoutTimer) | ||
if(!(evt instanceof Error)){ | ||
evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") ) | ||
} | ||
evt.statusCode = 0 | ||
return callback(evt, failureResponse) | ||
} | ||
|
||
// will load the data & process the response in a special response object | ||
function loadFunc() { | ||
if (aborted) return | ||
var status | ||
clearTimeout(timeoutTimer) | ||
if(options.useXDR && xhr.status===undefined) { | ||
//IE8 CORS GET successful response doesn't have a status field, but body is fine | ||
status = 200 | ||
} else { | ||
status = (xhr.status === 1223 ? 204 : xhr.status) | ||
} | ||
var response = failureResponse | ||
var err = null | ||
|
||
if (status !== 0){ | ||
response = { | ||
body: getBody(), | ||
statusCode: status, | ||
method: method, | ||
headers: {}, | ||
url: uri, | ||
rawRequest: xhr | ||
} | ||
if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE | ||
response.headers = parseHeaders(xhr.getAllResponseHeaders()) | ||
} | ||
} else { | ||
err = new Error("Internal XMLHttpRequest Error") | ||
} | ||
return callback(err, response, response.body) | ||
} | ||
|
||
var xhr = options.xhr || null | ||
|
||
if (!xhr) { | ||
if (options.cors || options.useXDR) { | ||
xhr = new createXHR.XDomainRequest() | ||
}else{ | ||
xhr = new createXHR.XMLHttpRequest() | ||
} | ||
} | ||
|
||
var key | ||
var aborted | ||
var uri = xhr.url = options.uri || options.url | ||
var method = xhr.method = options.method || "GET" | ||
var body = options.body || options.data | ||
var headers = xhr.headers = options.headers || {} | ||
var sync = !!options.sync | ||
var isJson = false | ||
var timeoutTimer | ||
var failureResponse = { | ||
body: undefined, | ||
headers: {}, | ||
statusCode: 0, | ||
method: method, | ||
url: uri, | ||
rawRequest: xhr | ||
} | ||
|
||
if ("json" in options && options.json !== false) { | ||
isJson = true | ||
headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json") //Don't override existing accept header declared by user | ||
if (method !== "GET" && method !== "HEAD") { | ||
headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json") //Don't override existing accept header declared by user | ||
body = JSON.stringify(options.json === true ? body : options.json) | ||
} | ||
} | ||
|
||
xhr.onreadystatechange = readystatechange | ||
xhr.onload = loadFunc | ||
xhr.onerror = errorFunc | ||
// IE9 must have onprogress be set to a unique function. | ||
xhr.onprogress = function () { | ||
// IE must die | ||
} | ||
xhr.onabort = function(){ | ||
aborted = true; | ||
} | ||
xhr.ontimeout = errorFunc | ||
xhr.open(method, uri, !sync, options.username, options.password) | ||
//has to be after open | ||
if(!sync) { | ||
xhr.withCredentials = !!options.withCredentials | ||
} | ||
// Cannot set timeout with sync request | ||
// not setting timeout on the xhr object, because of old webkits etc. not handling that correctly | ||
// both npm's request and jquery 1.x use this kind of timeout, so this is being consistent | ||
if (!sync && options.timeout > 0 ) { | ||
timeoutTimer = setTimeout(function(){ | ||
if (aborted) return | ||
aborted = true//IE9 may still call readystatechange | ||
xhr.abort("timeout") | ||
var e = new Error("XMLHttpRequest timeout") | ||
e.code = "ETIMEDOUT" | ||
errorFunc(e) | ||
}, options.timeout ) | ||
} | ||
|
||
if (xhr.setRequestHeader) { | ||
for(key in headers){ | ||
if(headers.hasOwnProperty(key)){ | ||
xhr.setRequestHeader(key, headers[key]) | ||
} | ||
} | ||
} else if (options.headers && !isEmpty(options.headers)) { | ||
throw new Error("Headers cannot be set on an XDomainRequest object") | ||
} | ||
|
||
if ("responseType" in options) { | ||
xhr.responseType = options.responseType | ||
} | ||
|
||
if ("beforeSend" in options && | ||
typeof options.beforeSend === "function" | ||
) { | ||
options.beforeSend(xhr) | ||
} | ||
|
||
// Microsoft Edge browser sends "undefined" when send is called with undefined value. | ||
// XMLHttpRequest spec says to pass null as body to indicate no body | ||
// See https://github.com/naugtur/xhr/issues/100. | ||
xhr.send(body || null) | ||
|
||
return xhr | ||
|
||
|
||
} | ||
|
||
function getXml(xhr) { | ||
if (xhr.responseType === "document") { | ||
return xhr.responseXML | ||
} | ||
var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror" | ||
if (xhr.responseType === "" && !firefoxBugTakenEffect) { | ||
return xhr.responseXML | ||
} | ||
|
||
return null | ||
} | ||
|
||
function noop() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters