Skip to content

Instantly share code, notes, and snippets.

@Noitidart
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Noitidart/9088113 to your computer and use it in GitHub Desktop.
Save Noitidart/9088113 to your computer and use it in GitHub Desktop.
_firefox-addon-snippet-HTTPWrapper - Forked from an addon long ago and slightly tweaked here and there. Designed for use in privelaged scope, meaning it does not need access to nsIDOMWindow for any properies or functions.
var XMLHttpRequest = Cc['@mozilla.org/xmlextras/xmlhttprequest;1'];
var timeoutTimer;
/**
* The following keys can be sent:
* onSuccess (required) a function called when the response is 2xx
* onFailure a function called when the response is not 2xx (IF onFailure and onTimeout are defined, when times out then onTimeout is executed only and not onFailure. IF onFailure is defined and onTimeout is NOT defined then when times out it will execute onFailure) (not called if aborted)
* username The username for basic auth
* password The password for basic auth
* overrideMimeType The mime type to use for non-XML response mime types
* timeout A timeout value in milliseconds for the response
* onTimeout A function to call if the request times out.
* body A string containing the entity body of the request
* contentType The content type of the entity body of the request
* headers A hash of optional headers
* returnHeaders Set to true if want headers returned in the "headers" var of the onSuccess etc
*/
function HTTP(method,url,options)
{
var requester = new XMLHttpRequest();
if (!timeoutTimer && options.timeout) {
timeoutTimer = Cc['@mozilla.org/timer;1'].createInstance(Ci.nsITimer);
}
if (!options.synchronizedRequest) {
requester.onreadystatechange = function() {
switch (requester.readyState) {
case 0:
if (options.onUnsent) {
options.onUnsent(requester);
}
break;
case 1:
if (options.onOpened) {
options.onOpened(requester);
}
break;
case 2:
if (options.onHeaders) {
options.onHeaders(requester);
}
break;
case 3:
if (options.onLoading) {
options.onLoading(requester);
}
break;
case 4:
if (options.timeout) {
timeoutTimer.cancel();
}
if (requester.status==0 || (requester.status>=200 && requester.status<300)) {
options.onSuccess(
requester.status,
requester.responseXML,
requester.responseText,
options.returnHeaders ? _HTTP_parseHeaders(requester.getAllResponseHeaders()) : null,
requester.statusText
);
} else {
if (options.onFailure) {
options.onFailure(
requester.status,
requester.responseXML,
requester.responseText,
options.returnHeaders ? _HTTP_parseHeaders(requester.getAllResponseHeaders()) : null,
requester.statusText
);
}
}
break;
}
}
}
if (options.overrideMimeType) {
requester.overrideMimeType(options.overrideMimeType);
}
if (options.username) {
requester.open(method,url,!options.synchronizedRequest,options.username,options.password);
} else {
requester.open(method,url,!options.synchronizedRequest);
}
if (options.timeout && !options.synchronizedRequest) {
var timeoutEvent = {
notify: function(timer) {
requester.abort();
var callback = options.onTimeout ? options.onTimeout : options.onFailure;
if (callback) {
callback(0, 'Operation timeout.');
}
}
}
timeoutTimer.initWithCallback(timeoutEvent, options.timeout, Ci.nsITimer.TYPE_ONE_SHOT);
}
if (options.headers) {
for (var name in options.headers) {
requester.setRequestHeader(name,options.headers[name]);
}
}
if (options.sendAsBinary) {
Cu.reportError('sending as binary');
requester.sendAsBinary(options.body);
} else if (options.body) {
requester.setRequestHeader("Content-Type",options.contentType);
requester.send(options.body);
} else {
requester.send(null);
}
if (options.synchronizedRequest) {
if (requester.status==0 || (requester.status>=200 && requester.status<300)) {
options.onSuccess(
requester.status,
requester.responseXML,
requester.responseText,
options.returnHeaders ? _HTTP_parseHeaders(requester.getAllResponseHeaders()) : null,
requester.statusText
);
} else {
if (options.onFailure) {
options.onFailure(
requester.status,
requester.responseXML,
requester.responseText,
options.returnHeaders ? _HTTP_parseHeaders(requester.getAllResponseHeaders()) : null,
requester.statusText
);
}
}
return {
abort: function() {
}
};
} else {
return {
abort: function() {
requester.abort();
if (options.timeout) {
timeoutTimer.cancel();
}
}
};
}
}
var _HTTP_HEADER_NAME = new RegExp("^([a-zA-Z0-9_-]+):");
function _HTTP_parseHeaders(headerText)
{
var headers = {};
if (headerText) {
var eol = headerText.indexOf("\n");
while (eol>=0) {
var line = headerText.substring(0,eol);
headerText = headerText.substring(eol+1);
while (headerText.length>0 && !headerText.match(_HTTP_HEADER_NAME)) {
eol = headerText.indexOf("\n");
var nextLine = eol<0 ? headerText : headerText.substring(0,eol);
line = line+' '+nextLine;
headerText = eol<0 ? "" : headerText.substring(eol+1);
}
// Parse the name value pair
var colon = line.indexOf(':');
var name = line.substring(0,colon);
var value = line.substring(colon+1);
headers[name] = value;
eol = headerText.indexOf("\n");
}
if (headerText.length>0) {
var colon = headerText.indexOf(':');
var name = headerText.substring(0,colon);
var value = headerText.substring(colon+1);
headers[name] = value;
}
}
return headers;
}
@Noitidart
Copy link
Author

Basic example:

HTTP('GET','http://www.bing.com/',{
onSuccess: function(status, responseXML, responseText, headers, statusText) {
alert('success')
},
onFailure: function(status, responseXML, responseText, headers, statusText) {
alert('failed')
}
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment