datahub/attachments/script/jquery.request.js

215 lines
6.0 KiB
JavaScript

(function() {
var define = window.define
if(!define) define = function(deps, definer) {
if(!window.jQuery)
throw new Error("Can't find jQuery");
return definer(window.jQuery);
}
define(['jquery'], function(jQuery) {
//
// request.jquery
//
var DEFAULT_TIMEOUT = 3 * 60 * 1000; // 3 minutes
function request(options, callback) {
if(typeof options === 'string')
options = {'uri':options};
else
options = JSON.parse(JSON.stringify(options)); // Use a duplicate for mutating.
if (!options.uri)
throw new Error("options.uri is a required argument");
else if(typeof options.uri != "string")
throw new Error("options.uri must be a string");
; $.each(['proxy', '_redirectsFollowed', 'maxRedirects', 'followRedirect'], function(i, opt) {
if(options[opt])
throw new Error("options." + opt + " is not supported");
})
options.method = options.method || 'GET';
options.headers = options.headers || {};
if(options.headers.host)
throw new Error("Options.headers.host is not supported");
/*
// Browsers do not like this.
if(options.body)
options.headers['content-length'] = options.body.length;
*/
var headers = {};
var beforeSend = function(xhr, settings) {
if(!options.headers.authorization && options.auth) {
debugger
options.headers.authorization = 'Basic ' + b64_enc(options.auth.username + ':' + options.auth.password);
}
for (var key in options.headers)
xhr.setRequestHeader(key, options.headers[key]);
}
// Establish a place where the callback arguments will go.
var result = [];
var onSuccess = function(data, reason, xhr) {
result = [null, xhr, data];
}
var onError = function (xhr, reason, er) {
var body = undefined;
if(!er) {
if(reason == 'timeout') {
er = new Error("Request timeout");
} else if(reason == 'error') {
if(xhr.status > 299 && xhr.responseText.length > 0) {
// Looks like HTTP worked, so there is no error as far as request is concerned. Simulate a success scenario.
er = null;
body = xhr.responseText;
}
} else {
er = new Error("Unknown error; reason = " + reason);
}
}
result = [er, xhr, body];
}
var onComplete = function(xhr, reason) {
if(result.length === 0)
result = [new Error("Result does not exist at completion time")];
return callback && callback.apply(this, result);
}
var cors_creds = !!( options.creds || options.withCredentials );
return jQuery.ajax({ 'async' : true
, 'cache' : (options.cache || false)
, 'contentType': (options.headers['content-type'] || 'application/x-www-form-urlencoded')
, 'type' : options.method
, 'url' : options.uri
, 'data' : (options.body || undefined)
, 'timeout' : (options.timeout || request.DEFAULT_TIMEOUT)
, 'dataType' : 'text'
, 'processData': false
, 'beforeSend' : beforeSend
, 'success' : onSuccess
, 'error' : onError
, 'complete' : onComplete
, 'xhrFields' : { 'withCredentials': cors_creds
}
});
};
request.withCredentials = false;
request.DEFAULT_TIMEOUT = DEFAULT_TIMEOUT;
var shortcuts = [ 'get', 'put', 'post', 'head' ];
$.each(shortcuts, function(i, shortcut) {
var method = shortcut.toUpperCase();
var func = shortcut.toLowerCase();
request[func] = function(opts) {
if(typeof opts === 'string')
opts = {'method':method, 'uri':opts};
else {
opts = JSON.parse(JSON.stringify(opts));
opts.method = method;
}
var args = [opts].concat(Array.prototype.slice.apply(arguments, [1]));
return request.apply(this, args);
}
})
request.json = function(options, callback) {
options = JSON.parse(JSON.stringify(options));
options.headers = options.headers || {};
options.headers['accept'] = options.headers['accept'] || 'application/json';
if(options.method !== 'GET')
options.headers['content-type'] = 'application/json';
return request(options, function(er, resp, body) {
if(!er)
body = JSON.parse(body)
return callback && callback(er, resp, body);
})
}
request.couch = function(options, callback) {
return request.json(options, function(er, resp, body) {
if(er)
return callback && callback(er, resp, body);
if((resp.status < 200 || resp.status > 299) && body.error)
// The body is a Couch JSON object indicating the error.
return callback && callback(body, resp);
return callback && callback(er, resp, body);
})
}
jQuery(document).ready(function() {
jQuery.request = request;
})
return request;
});
//
// Utility
//
// MIT License from http://phpjs.org/functions/base64_encode:358
function b64_enc (data) {
// Encodes string using MIME base64 algorithm
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var o1, o2, o3, h1, h2, h3, h4, bits, i = 0, ac = 0, enc="", tmp_arr = [];
if (!data) {
return data;
}
// assume utf8 data
// data = this.utf8_encode(data+'');
do { // pack three octets into four hexets
o1 = data.charCodeAt(i++);
o2 = data.charCodeAt(i++);
o3 = data.charCodeAt(i++);
bits = o1<<16 | o2<<8 | o3;
h1 = bits>>18 & 0x3f;
h2 = bits>>12 & 0x3f;
h3 = bits>>6 & 0x3f;
h4 = bits & 0x3f;
// use hexets to index into b64, and append result to encoded string
tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
} while (i < data.length);
enc = tmp_arr.join('');
switch (data.length % 3) {
case 1:
enc = enc.slice(0, -2) + '==';
break;
case 2:
enc = enc.slice(0, -1) + '=';
break;
}
return enc;
}
})();