0
0
Fork 1
mirror of https://mau.dev/maunium/synapse.git synced 2024-12-30 03:14:10 +01:00
synapse/docs/client-server/web/files/shred.bundle.js

2765 lines
No EOL
86 KiB
JavaScript
Raw Blame History

var require = function (file, cwd) {
var resolved = require.resolve(file, cwd || '/');
var mod = require.modules[resolved];
if (!mod) throw new Error(
'Failed to resolve module ' + file + ', tried ' + resolved
);
var res = mod._cached ? mod._cached : mod();
return res;
}
require.paths = [];
require.modules = {};
require.extensions = [".js",".coffee"];
require._core = {
'assert': true,
'events': true,
'fs': true,
'path': true,
'vm': true
};
require.resolve = (function () {
return function (x, cwd) {
if (!cwd) cwd = '/';
if (require._core[x]) return x;
var path = require.modules.path();
var y = cwd || '.';
if (x.match(/^(?:\.\.?\/|\/)/)) {
var m = loadAsFileSync(path.resolve(y, x))
|| loadAsDirectorySync(path.resolve(y, x));
if (m) return m;
}
var n = loadNodeModulesSync(x, y);
if (n) return n;
throw new Error("Cannot find module '" + x + "'");
function loadAsFileSync (x) {
if (require.modules[x]) {
return x;
}
for (var i = 0; i < require.extensions.length; i++) {
var ext = require.extensions[i];
if (require.modules[x + ext]) return x + ext;
}
}
function loadAsDirectorySync (x) {
x = x.replace(/\/+$/, '');
var pkgfile = x + '/package.json';
if (require.modules[pkgfile]) {
var pkg = require.modules[pkgfile]();
var b = pkg.browserify;
if (typeof b === 'object' && b.main) {
var m = loadAsFileSync(path.resolve(x, b.main));
if (m) return m;
}
else if (typeof b === 'string') {
var m = loadAsFileSync(path.resolve(x, b));
if (m) return m;
}
else if (pkg.main) {
var m = loadAsFileSync(path.resolve(x, pkg.main));
if (m) return m;
}
}
return loadAsFileSync(x + '/index');
}
function loadNodeModulesSync (x, start) {
var dirs = nodeModulesPathsSync(start);
for (var i = 0; i < dirs.length; i++) {
var dir = dirs[i];
var m = loadAsFileSync(dir + '/' + x);
if (m) return m;
var n = loadAsDirectorySync(dir + '/' + x);
if (n) return n;
}
var m = loadAsFileSync(x);
if (m) return m;
}
function nodeModulesPathsSync (start) {
var parts;
if (start === '/') parts = [ '' ];
else parts = path.normalize(start).split('/');
var dirs = [];
for (var i = parts.length - 1; i >= 0; i--) {
if (parts[i] === 'node_modules') continue;
var dir = parts.slice(0, i + 1).join('/') + '/node_modules';
dirs.push(dir);
}
return dirs;
}
};
})();
require.alias = function (from, to) {
var path = require.modules.path();
var res = null;
try {
res = require.resolve(from + '/package.json', '/');
}
catch (err) {
res = require.resolve(from, '/');
}
var basedir = path.dirname(res);
var keys = (Object.keys || function (obj) {
var res = [];
for (var key in obj) res.push(key)
return res;
})(require.modules);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (key.slice(0, basedir.length + 1) === basedir + '/') {
var f = key.slice(basedir.length);
require.modules[to + f] = require.modules[basedir + f];
}
else if (key === basedir) {
require.modules[to] = require.modules[basedir];
}
}
};
require.define = function (filename, fn) {
var dirname = require._core[filename]
? ''
: require.modules.path().dirname(filename)
;
var require_ = function (file) {
return require(file, dirname)
};
require_.resolve = function (name) {
return require.resolve(name, dirname);
};
require_.modules = require.modules;
require_.define = require.define;
var module_ = { exports : {} };
require.modules[filename] = function () {
require.modules[filename]._cached = module_.exports;
fn.call(
module_.exports,
require_,
module_,
module_.exports,
dirname,
filename
);
require.modules[filename]._cached = module_.exports;
return module_.exports;
};
};
if (typeof process === 'undefined') process = {};
if (!process.nextTick) process.nextTick = (function () {
var queue = [];
var canPost = typeof window !== 'undefined'
&& window.postMessage && window.addEventListener
;
if (canPost) {
window.addEventListener('message', function (ev) {
if (ev.source === window && ev.data === 'browserify-tick') {
ev.stopPropagation();
if (queue.length > 0) {
var fn = queue.shift();
fn();
}
}
}, true);
}
return function (fn) {
if (canPost) {
queue.push(fn);
window.postMessage('browserify-tick', '*');
}
else setTimeout(fn, 0);
};
})();
if (!process.title) process.title = 'browser';
if (!process.binding) process.binding = function (name) {
if (name === 'evals') return require('vm')
else throw new Error('No such module')
};
if (!process.cwd) process.cwd = function () { return '.' };
require.define("path", function (require, module, exports, __dirname, __filename) {
function filter (xs, fn) {
var res = [];
for (var i = 0; i < xs.length; i++) {
if (fn(xs[i], i, xs)) res.push(xs[i]);
}
return res;
}
// resolves . and .. elements in a path array with directory names there
// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length; i >= 0; i--) {
var last = parts[i];
if (last == '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}
return parts;
}
// Regex to split a filename into [*, dir, basename, ext]
// posix version
var splitPathRe = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/;
// path.resolve([from ...], to)
// posix version
exports.resolve = function() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) {
var path = (i >= 0)
? arguments[i]
: process.cwd();
// Skip empty and invalid entries
if (typeof path !== 'string' || !path) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charAt(0) === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
return !!p;
}), !resolvedAbsolute).join('/');
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
};
// path.normalize(path)
// posix version
exports.normalize = function(path) {
var isAbsolute = path.charAt(0) === '/',
trailingSlash = path.slice(-1) === '/';
// Normalize the path
path = normalizeArray(filter(path.split('/'), function(p) {
return !!p;
}), !isAbsolute).join('/');
if (!path && !isAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}
return (isAbsolute ? '/' : '') + path;
};
// posix version
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(filter(paths, function(p, index) {
return p && typeof p === 'string';
}).join('/'));
};
exports.dirname = function(path) {
var dir = splitPathRe.exec(path)[1] || '';
var isWindows = false;
if (!dir) {
// No dirname
return '.';
} else if (dir.length === 1 ||
(isWindows && dir.length <= 3 && dir.charAt(1) === ':')) {
// It is just a slash or a drive letter with a slash
return dir;
} else {
// It is a full dirname, strip trailing slash
return dir.substring(0, dir.length - 1);
}
};
exports.basename = function(path, ext) {
var f = splitPathRe.exec(path)[2] || '';
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};
exports.extname = function(path) {
return splitPathRe.exec(path)[3] || '';
};
});
require.define("/shred.js", function (require, module, exports, __dirname, __filename) {
// Shred is an HTTP client library intended to simplify the use of Node's
// built-in HTTP library. In particular, we wanted to make it easier to interact
// with HTTP-based APIs.
//
// See the [examples](./examples.html) for more details.
// Ax is a nice logging library we wrote. You can use any logger, providing it
// has `info`, `warn`, `debug`, and `error` methods that take a string.
var Ax = require("ax")
, CookieJarLib = require( "cookiejar" )
, CookieJar = CookieJarLib.CookieJar
;
// Shred takes some options, including a logger and request defaults.
var Shred = function(options) {
options = (options||{});
this.agent = options.agent;
this.defaults = options.defaults||{};
this.log = options.logger||(new Ax({ level: "info" }));
this._sharedCookieJar = new CookieJar();
this.logCurl = options.logCurl || false;
};
// Most of the real work is done in the request and reponse classes.
Shred.Request = require("./shred/request");
Shred.Response = require("./shred/response");
// The `request` method kicks off a new request, instantiating a new `Request`
// object and passing along whatever default options we were given.
Shred.prototype = {
request: function(options) {
options.logger = this.log;
options.logCurl = options.logCurl || this.logCurl;
options.cookieJar = ( 'cookieJar' in options ) ? options.cookieJar : this._sharedCookieJar; // let them set cookieJar = null
options.agent = options.agent || this.agent;
// fill in default options
for (var key in this.defaults) {
if (this.defaults.hasOwnProperty(key) && !options[key]) {
options[key] = this.defaults[key]
}
}
return new Shred.Request(options);
}
};
// Define a bunch of convenience methods so that you don't have to include
// a `method` property in your request options.
"get put post delete".split(" ").forEach(function(method) {
Shred.prototype[method] = function(options) {
options.method = method;
return this.request(options);
};
});
module.exports = Shred;
});
require.define("/node_modules/ax/package.json", function (require, module, exports, __dirname, __filename) {
module.exports = {"main":"./lib/ax.js"}
});
require.define("/node_modules/ax/lib/ax.js", function (require, module, exports, __dirname, __filename) {
var inspect = require("util").inspect
, fs = require("fs")
;
// this is a quick-and-dirty logger. there are other nicer loggers out there
// but the ones i found were also somewhat involved. this one has a Ruby
// logger type interface
//
// we can easily replace this, provide the info, debug, etc. methods are the
// same. or, we can change Haiku to use a more standard node.js interface
var format = function(level,message) {
var debug = (level=="debug"||level=="error");
if (!message) { return message.toString(); }
if (typeof(message) == "object") {
if (message instanceof Error && debug) {
return message.stack;
} else {
return inspect(message);
}
} else {
return message.toString();
}
};
var noOp = function(message) { return this; }
var makeLogger = function(level,fn) {
return function(message) {
this.stream.write(this.format(level, message)+"\n");
return this;
}
};
var Logger = function(options) {
var logger = this;
var options = options||{};
// Default options
options.level = options.level || "info";
options.timestamp = options.timestamp || true;
options.prefix = options.prefix || "";
logger.options = options;
// Allows a prefix to be added to the message.
//
// var logger = new Ax({ module: 'Haiku' })
// logger.warn('this is going to be awesome!');
// //=> Haiku: this is going to be awesome!
//
if (logger.options.module){
logger.options.prefix = logger.options.module;
}
// Write to stderr or a file
if (logger.options.file){
logger.stream = fs.createWriteStream(logger.options.file, {"flags": "a"});
} else {
if(process.title === "node")
logger.stream = process.stderr;
else if(process.title === "browser")
logger.stream = function () {
// Work around weird console context issue: http://code.google.com/p/chromium/issues/detail?id=48662
return console[logger.options.level].apply(console, arguments);
};
}
switch(logger.options.level){
case 'debug':
['debug', 'info', 'warn'].forEach(function (level) {
logger[level] = Logger.writer(level);
});
case 'info':
['info', 'warn'].forEach(function (level) {
logger[level] = Logger.writer(level);
});
case 'warn':
logger.warn = Logger.writer('warn');
}
}
// Used to define logger methods
Logger.writer = function(level){
return function(message){
var logger = this;
if(process.title === "node")
logger.stream.write(logger.format(level, message) + '\n');
else if(process.title === "browser")
logger.stream(logger.format(level, message) + '\n');
};
}
Logger.prototype = {
info: function(){},
debug: function(){},
warn: function(){},
error: Logger.writer('error'),
format: function(level, message){
if (! message) return '';
var logger = this
, prefix = logger.options.prefix
, timestamp = logger.options.timestamp ? " " + (new Date().toISOString()) : ""
;
return (prefix + timestamp + ": " + message);
}
};
module.exports = Logger;
});
require.define("util", function (require, module, exports, __dirname, __filename) {
// todo
});
require.define("fs", function (require, module, exports, __dirname, __filename) {
// nothing to see here... no file methods for the browser
});
require.define("/node_modules/cookiejar/package.json", function (require, module, exports, __dirname, __filename) {
module.exports = {"main":"cookiejar.js"}
});
require.define("/node_modules/cookiejar/cookiejar.js", function (require, module, exports, __dirname, __filename) {
exports.CookieAccessInfo=CookieAccessInfo=function CookieAccessInfo(domain,path,secure,script) {
if(this instanceof CookieAccessInfo) {
this.domain=domain||undefined;
this.path=path||"/";
this.secure=!!secure;
this.script=!!script;
return this;
}
else {
return new CookieAccessInfo(domain,path,secure,script)
}
}
exports.Cookie=Cookie=function Cookie(cookiestr) {
if(cookiestr instanceof Cookie) {
return cookiestr;
}
else {
if(this instanceof Cookie) {
this.name = null;
this.value = null;
this.expiration_date = Infinity;
this.path = "/";
this.domain = null;
this.secure = false; //how to define?
this.noscript = false; //httponly
if(cookiestr) {
this.parse(cookiestr)
}
return this;
}
return new Cookie(cookiestr)
}
}
Cookie.prototype.toString = function toString() {
var str=[this.name+"="+this.value];
if(this.expiration_date !== Infinity) {
str.push("expires="+(new Date(this.expiration_date)).toGMTString());
}
if(this.domain) {
str.push("domain="+this.domain);
}
if(this.path) {
str.push("path="+this.path);
}
if(this.secure) {
str.push("secure");
}
if(this.noscript) {
str.push("httponly");
}
return str.join("; ");
}
Cookie.prototype.toValueString = function toValueString() {
return this.name+"="+this.value;
}
var cookie_str_splitter=/[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g
Cookie.prototype.parse = function parse(str) {
if(this instanceof Cookie) {
var parts=str.split(";")
, pair=parts[0].match(/([^=]+)=((?:.|\n)*)/)
, key=pair[1]
, value=pair[2];
this.name = key;
this.value = value;
for(var i=1;i<parts.length;i++) {
pair=parts[i].match(/([^=]+)(?:=((?:.|\n)*))?/)
, key=pair[1].trim().toLowerCase()
, value=pair[2];
switch(key) {
case "httponly":
this.noscript = true;
break;
case "expires":
this.expiration_date = value
? Number(Date.parse(value))
: Infinity;
break;
case "path":
this.path = value
? value.trim()
: "";
break;
case "domain":
this.domain = value
? value.trim()
: "";
break;
case "secure":
this.secure = true;
break
}
}
return this;
}
return new Cookie().parse(str)
}
Cookie.prototype.matches = function matches(access_info) {
if(this.noscript && access_info.script
|| this.secure && !access_info.secure
|| !this.collidesWith(access_info)) {
return false
}
return true;
}
Cookie.prototype.collidesWith = function collidesWith(access_info) {
if((this.path && !access_info.path) || (this.domain && !access_info.domain)) {
return false
}
if(this.path && access_info.path.indexOf(this.path) !== 0) {
return false;
}
if (this.domain===access_info.domain) {
return true;
}
else if(this.domain && this.domain.charAt(0)===".")
{
var wildcard=access_info.domain.indexOf(this.domain.slice(1))
if(wildcard===-1 || wildcard!==access_info.domain.length-this.domain.length+1) {
return false;
}
}
else if(this.domain){
return false
}
return true;
}
exports.CookieJar=CookieJar=function CookieJar() {
if(this instanceof CookieJar) {
var cookies = {} //name: [Cookie]
this.setCookie = function setCookie(cookie) {
cookie = Cookie(cookie);
//Delete the cookie if the set is past the current time
var remove = cookie.expiration_date <= Date.now();
if(cookie.name in cookies) {
var cookies_list = cookies[cookie.name];
for(var i=0;i<cookies_list.length;i++) {
var collidable_cookie = cookies_list[i];
if(collidable_cookie.collidesWith(cookie)) {
if(remove) {
cookies_list.splice(i,1);
if(cookies_list.length===0) {
delete cookies[cookie.name]
}
return false;
}
else {
return cookies_list[i]=cookie;
}
}
}
if(remove) {
return false;
}
cookies_list.push(cookie);
return cookie;
}
else if(remove){
return false;
}
else {
return cookies[cookie.name]=[cookie];
}
}
//returns a cookie
this.getCookie = function getCookie(cookie_name,access_info) {
var cookies_list = cookies[cookie_name];
for(var i=0;i<cookies_list.length;i++) {
var cookie = cookies_list[i];
if(cookie.expiration_date <= Date.now()) {
if(cookies_list.length===0) {
delete cookies[cookie.name]
}
continue;
}
if(cookie.matches(access_info)) {
return cookie;
}
}
}
//returns a list of cookies
this.getCookies = function getCookies(access_info) {
var matches=[];
for(var cookie_name in cookies) {
var cookie=this.getCookie(cookie_name,access_info);
if (cookie) {
matches.push(cookie);
}
}
matches.toString=function toString(){return matches.join(":");}
matches.toValueString=function() {return matches.map(function(c){return c.toValueString();}).join(';');}
return matches;
}
return this;
}
return new CookieJar()
}
//returns list of cookies that were set correctly
CookieJar.prototype.setCookies = function setCookies(cookies) {
cookies=Array.isArray(cookies)
?cookies
:cookies.split(cookie_str_splitter);
var successful=[]
for(var i=0;i<cookies.length;i++) {
var cookie = Cookie(cookies[i]);
if(this.setCookie(cookie)) {
successful.push(cookie);
}
}
return successful;
}
});
require.define("/shred/request.js", function (require, module, exports, __dirname, __filename) {
// The request object encapsulates a request, creating a Node.js HTTP request and
// then handling the response.
var HTTP = require("http")
, HTTPS = require("https")
, parseUri = require("./parseUri")
, Emitter = require('events').EventEmitter
, sprintf = require("sprintf").sprintf
, Response = require("./response")
, HeaderMixins = require("./mixins/headers")
, Content = require("./content")
;
var STATUS_CODES = HTTP.STATUS_CODES || {
100 : 'Continue',
101 : 'Switching Protocols',
102 : 'Processing', // RFC 2518, obsoleted by RFC 4918
200 : 'OK',
201 : 'Created',
202 : 'Accepted',
203 : 'Non-Authoritative Information',
204 : 'No Content',
205 : 'Reset Content',
206 : 'Partial Content',
207 : 'Multi-Status', // RFC 4918
300 : 'Multiple Choices',
301 : 'Moved Permanently',
302 : 'Moved Temporarily',
303 : 'See Other',
304 : 'Not Modified',
305 : 'Use Proxy',
307 : 'Temporary Redirect',
400 : 'Bad Request',
401 : 'Unauthorized',
402 : 'Payment Required',
403 : 'Forbidden',
404 : 'Not Found',
405 : 'Method Not Allowed',
406 : 'Not Acceptable',
407 : 'Proxy Authentication Required',
408 : 'Request Time-out',
409 : 'Conflict',
410 : 'Gone',
411 : 'Length Required',
412 : 'Precondition Failed',
413 : 'Request Entity Too Large',
414 : 'Request-URI Too Large',
415 : 'Unsupported Media Type',
416 : 'Requested Range Not Satisfiable',
417 : 'Expectation Failed',
418 : 'I\'m a teapot', // RFC 2324
422 : 'Unprocessable Entity', // RFC 4918
423 : 'Locked', // RFC 4918
424 : 'Failed Dependency', // RFC 4918
425 : 'Unordered Collection', // RFC 4918
426 : 'Upgrade Required', // RFC 2817
500 : 'Internal Server Error',
501 : 'Not Implemented',
502 : 'Bad Gateway',
503 : 'Service Unavailable',
504 : 'Gateway Time-out',
505 : 'HTTP Version not supported',
506 : 'Variant Also Negotiates', // RFC 2295
507 : 'Insufficient Storage', // RFC 4918
509 : 'Bandwidth Limit Exceeded',
510 : 'Not Extended' // RFC 2774
};
// The Shred object itself constructs the `Request` object. You should rarely
// need to do this directly.
var Request = function(options) {
this.log = options.logger;
this.cookieJar = options.cookieJar;
this.encoding = options.encoding;
this.logCurl = options.logCurl;
processOptions(this,options||{});
createRequest(this);
};
// A `Request` has a number of properties, many of which help with details like
// URL parsing or defaulting the port for the request.
Object.defineProperties(Request.prototype, {
// - **url**. You can set the `url` property with a valid URL string and all the
// URL-related properties (host, port, etc.) will be automatically set on the
// request object.
url: {
get: function() {
if (!this.scheme) { return null; }
return sprintf("%s://%s:%s%s",
this.scheme, this.host, this.port,
(this.proxy ? "/" : this.path) +
(this.query ? ("?" + this.query) : ""));
},
set: function(_url) {
_url = parseUri(_url);
this.scheme = _url.protocol;
this.host = _url.host;
this.port = _url.port;
this.path = _url.path;
this.query = _url.query;
return this;
},
enumerable: true
},
// - **headers**. Returns a hash representing the request headers. You can't set
// this directly, only get it. You can add or modify headers by using the
// `setHeader` or `setHeaders` method. This ensures that the headers are
// normalized - that is, you don't accidentally send `Content-Type` and
// `content-type` headers. Keep in mind that if you modify the returned hash,
// it will *not* modify the request headers.
headers: {
get: function() {
return this.getHeaders();
},
enumerable: true
},
// - **port**. Unless you set the `port` explicitly or include it in the URL, it
// will default based on the scheme.
port: {
get: function() {
if (!this._port) {
switch(this.scheme) {
case "https": return this._port = 443;
case "http":
default: return this._port = 80;
}
}
return this._port;
},
set: function(value) { this._port = value; return this; },
enumerable: true
},
// - **method**. The request method - `get`, `put`, `post`, etc. that will be
// used to make the request. Defaults to `get`.
method: {
get: function() {
return this._method = (this._method||"GET");
},
set: function(value) {
this._method = value; return this;
},
enumerable: true
},
// - **query**. Can be set either with a query string or a hash (object). Get
// will always return a properly escaped query string or null if there is no
// query component for the request.
query: {
get: function() {return this._query;},
set: function(value) {
var stringify = function (hash) {
var query = "";
for (var key in hash) {
query += encodeURIComponent(key) + '=' + encodeURIComponent(hash[key]) + '&';
}
// Remove the last '&'
query = query.slice(0, -1);
return query;
}
if (value) {
if (typeof value === 'object') {
value = stringify(value);
}
this._query = value;
} else {
this._query = "";
}
return this;
},
enumerable: true
},
// - **parameters**. This will return the query parameters in the form of a hash
// (object).
parameters: {
get: function() { return QueryString.parse(this._query||""); },
enumerable: true
},
// - **content**. (Aliased as `body`.) Set this to add a content entity to the
// request. Attempts to use the `content-type` header to determine what to do
// with the content value. Get this to get back a [`Content`
// object](./content.html).
body: {
get: function() { return this._body; },
set: function(value) {
this._body = new Content({
data: value,
type: this.getHeader("Content-Type")
});
this.setHeader("Content-Type",this.content.type);
this.setHeader("Content-Length",this.content.length);
return this;
},
enumerable: true
},
// - **timeout**. Used to determine how long to wait for a response. Does not
// distinguish between connect timeouts versus request timeouts. Set either in
// milliseconds or with an object with temporal attributes (hours, minutes,
// seconds) and convert it into milliseconds. Get will always return
// milliseconds.
timeout: {
get: function() { return this._timeout; }, // in milliseconds
set: function(timeout) {
var request = this
, milliseconds = 0;
;
if (!timeout) return this;
if (typeof timeout==="number") { milliseconds = timeout; }
else {
milliseconds = (timeout.milliseconds||0) +
(1000 * ((timeout.seconds||0) +
(60 * ((timeout.minutes||0) +
(60 * (timeout.hours||0))))));
}
this._timeout = milliseconds;
return this;
},
enumerable: true
}
});
// Alias `body` property to `content`. Since the [content object](./content.html)
// has a `body` attribute, it's preferable to use `content` since you can then
// access the raw content data using `content.body`.
Object.defineProperty(Request.prototype,"content",
Object.getOwnPropertyDescriptor(Request.prototype, "body"));
// The `Request` object can be pretty overwhelming to view using the built-in
// Node.js inspect method. We want to make it a bit more manageable. This
// probably goes [too far in the other
// direction](https://github.com/spire-io/shred/issues/2).
Request.prototype.inspect = function () {
var request = this;
var headers = this.format_headers();
var summary = ["<Shred Request> ", request.method.toUpperCase(),
request.url].join(" ")
return [ summary, "- Headers:", headers].join("\n");
};
Request.prototype.format_headers = function () {
var array = []
var headers = this._headers
for (var key in headers) {
if (headers.hasOwnProperty(key)) {
var value = headers[key]
array.push("\t" + key + ": " + value);
}
}
return array.join("\n");
};
// Allow chainable 'on's: shred.get({ ... }).on( ... ). You can pass in a
// single function, a pair (event, function), or a hash:
// { event: function, event: function }
Request.prototype.on = function (eventOrHash, listener) {
var emitter = this.emitter;
// Pass in a single argument as a function then make it the default response handler
if (arguments.length === 1 && typeof(eventOrHash) === 'function') {
emitter.on('response', eventOrHash);
} else if (arguments.length === 1 && typeof(eventOrHash) === 'object') {
for (var key in eventOrHash) {
if (eventOrHash.hasOwnProperty(key)) {
emitter.on(key, eventOrHash[key]);
}
}
} else {
emitter.on(eventOrHash, listener);
}
return this;
};
// Add in the header methods. Again, these ensure we don't get the same header
// multiple times with different case conventions.
HeaderMixins.gettersAndSetters(Request);
// `processOptions` is called from the constructor to handle all the work
// associated with making sure we do our best to ensure we have a valid request.
var processOptions = function(request,options) {
request.log.debug("Processing request options ..");
// We'll use `request.emitter` to manage the `on` event handlers.
request.emitter = (new Emitter);
request.agent = options.agent;
// Set up the handlers ...
if (options.on) {
for (var key in options.on) {
if (options.on.hasOwnProperty(key)) {
request.emitter.on(key, options.on[key]);
}
}
}
// Make sure we were give a URL or a host
if (!options.url && !options.host) {
request.emitter.emit("request_error",
new Error("No url or url options (host, port, etc.)"));
return;
}
// Allow for the [use of a proxy](http://www.jmarshall.com/easy/http/#proxies).
if (options.url) {
if (options.proxy) {
request.url = options.proxy;
request.path = options.url;
} else {
request.url = options.url;
}
}
// Set the remaining options.
request.query = options.query||options.parameters||request.query ;
request.method = options.method;
request.setHeader("user-agent",options.agent||"Shred");
request.setHeaders(options.headers);
if (request.cookieJar) {
var cookies = request.cookieJar.getCookies( CookieAccessInfo( request.host, request.path ) );
if (cookies.length) {
var cookieString = request.getHeader('cookie')||'';
for (var cookieIndex = 0; cookieIndex < cookies.length; ++cookieIndex) {
if ( cookieString.length && cookieString[ cookieString.length - 1 ] != ';' )
{
cookieString += ';';
}
cookieString += cookies[ cookieIndex ].name + '=' + cookies[ cookieIndex ].value + ';';
}
request.setHeader("cookie", cookieString);
}
}
// The content entity can be set either using the `body` or `content` attributes.
if (options.body||options.content) {
request.content = options.body||options.content;
}
request.timeout = options.timeout;
};
// `createRequest` is also called by the constructor, after `processOptions`.
// This actually makes the request and processes the response, so `createRequest`
// is a bit of a misnomer.
var createRequest = function(request) {
var timeout ;
request.log.debug("Creating request ..");
request.log.debug(request);
var reqParams = {
host: request.host,
port: request.port,
method: request.method,
path: request.path + (request.query ? '?'+request.query : ""),
headers: request.getHeaders(),
// Node's HTTP/S modules will ignore this, but we are using the
// browserify-http module in the browser for both HTTP and HTTPS, and this
// is how you differentiate the two.
scheme: request.scheme,
// Use a provided agent. 'Undefined' is the default, which uses a global
// agent.
agent: request.agent
};
if (request.logCurl) {
logCurl(request);
}
var http = request.scheme == "http" ? HTTP : HTTPS;
// Set up the real request using the selected library. The request won't be
// sent until we call `.end()`.
request._raw = http.request(reqParams, function(response) {
request.log.debug("Received response ..");
// We haven't timed out and we have a response, so make sure we clear the
// timeout so it doesn't fire while we're processing the response.
clearTimeout(timeout);
// Construct a Shred `Response` object from the response. This will stream
// the response, thus the need for the callback. We can access the response
// entity safely once we're in the callback.
response = new Response(response, request, function(response) {
// Set up some event magic. The precedence is given first to
// status-specific handlers, then to responses for a given event, and then
// finally to the more general `response` handler. In the last case, we
// need to first make sure we're not dealing with a a redirect.
var emit = function(event) {
var emitter = request.emitter;
var textStatus = STATUS_CODES[response.status] ? STATUS_CODES[response.status].toLowerCase() : null;
if (emitter.listeners(response.status).length > 0 || emitter.listeners(textStatus).length > 0) {
emitter.emit(response.status, response);
emitter.emit(textStatus, response);
} else {
if (emitter.listeners(event).length>0) {
emitter.emit(event, response);
} else if (!response.isRedirect) {
emitter.emit("response", response);
//console.warn("Request has no event listener for status code " + response.status);
}
}
};
// Next, check for a redirect. We simply repeat the request with the URL
// given in the `Location` header. We fire a `redirect` event.
if (response.isRedirect) {
request.log.debug("Redirecting to "
+ response.getHeader("Location"));
request.url = response.getHeader("Location");
emit("redirect");
createRequest(request);
// Okay, it's not a redirect. Is it an error of some kind?
} else if (response.isError) {
emit("error");
} else {
// It looks like we're good shape. Trigger the `success` event.
emit("success");
}
});
});
// We're still setting up the request. Next, we're going to handle error cases
// where we have no response. We don't emit an error event because that event
// takes a response. We don't response handlers to have to check for a null
// value. However, we [should introduce a different event
// type](https://github.com/spire-io/shred/issues/3) for this type of error.
request._raw.on("error", function(error) {
request.emitter.emit("request_error", error);
});
request._raw.on("socket", function(socket) {
request.emitter.emit("socket", socket);
});
// TCP timeouts should also trigger the "response_error" event.
request._raw.on('socket', function () {
request._raw.socket.on('timeout', function () {
// This should trigger the "error" event on the raw request, which will
// trigger the "response_error" on the shred request.
request._raw.abort();
});
});
// We're almost there. Next, we need to write the request entity to the
// underlying request object.
if (request.content) {
request.log.debug("Streaming body: '" +
request.content.data.slice(0,59) + "' ... ");
request._raw.write(request.content.data);
}
// Finally, we need to set up the timeout. We do this last so that we don't
// start the clock ticking until the last possible moment.
if (request.timeout) {
timeout = setTimeout(function() {
request.log.debug("Timeout fired, aborting request ...");
request._raw.abort();
request.emitter.emit("timeout", request);
},request.timeout);
}
// The `.end()` method will cause the request to fire. Technically, it might
// have already sent the headers and body.
request.log.debug("Sending request ...");
request._raw.end();
};
// Logs the curl command for the request.
var logCurl = function (req) {
var headers = req.getHeaders();
var headerString = "";
for (var key in headers) {
headerString += '-H "' + key + ": " + headers[key] + '" ';
}
var bodyString = ""
if (req.content) {
bodyString += "-d '" + req.content.body + "' ";
}
var query = req.query ? '?' + req.query : "";
console.log("curl " +
"-X " + req.method.toUpperCase() + " " +
req.scheme + "://" + req.host + ":" + req.port + req.path + query + " " +
headerString +
bodyString
);
};
module.exports = Request;
});
require.define("http", function (require, module, exports, __dirname, __filename) {
// todo
});
require.define("https", function (require, module, exports, __dirname, __filename) {
// todo
});
require.define("/shred/parseUri.js", function (require, module, exports, __dirname, __filename) {
// parseUri 1.2.2
// (c) Steven Levithan <stevenlevithan.com>
// MIT License
function parseUri (str) {
var o = parseUri.options,
m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
uri = {},
i = 14;
while (i--) uri[o.key[i]] = m[i] || "";
uri[o.q.name] = {};
uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
if ($1) uri[o.q.name][$1] = $2;
});
return uri;
};
parseUri.options = {
strictMode: false,
key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
q: {
name: "queryKey",
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
},
parser: {
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
}
};
module.exports = parseUri;
});
require.define("events", function (require, module, exports, __dirname, __filename) {
if (!process.EventEmitter) process.EventEmitter = function () {};
var EventEmitter = exports.EventEmitter = process.EventEmitter;
var isArray = typeof Array.isArray === 'function'
? Array.isArray
: function (xs) {
return Object.toString.call(xs) === '[object Array]'
}
;
// By default EventEmitters will print a warning if more than
// 10 listeners are added to it. This is a useful default which
// helps finding memory leaks.
//
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
var defaultMaxListeners = 10;
EventEmitter.prototype.setMaxListeners = function(n) {
if (!this._events) this._events = {};
this._events.maxListeners = n;
};
EventEmitter.prototype.emit = function(type) {
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events || !this._events.error ||
(isArray(this._events.error) && !this._events.error.length))
{
if (arguments[1] instanceof Error) {
throw arguments[1]; // Unhandled 'error' event
} else {
throw new Error("Uncaught, unspecified 'error' event.");
}
return false;
}
}
if (!this._events) return false;
var handler = this._events[type];
if (!handler) return false;
if (typeof handler == 'function') {
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
var args = Array.prototype.slice.call(arguments, 1);
handler.apply(this, args);
}
return true;
} else if (isArray(handler)) {
var args = Array.prototype.slice.call(arguments, 1);
var listeners = handler.slice();
for (var i = 0, l = listeners.length; i < l; i++) {
listeners[i].apply(this, args);
}
return true;
} else {
return false;
}
};
// EventEmitter is defined in src/node_events.cc
// EventEmitter.prototype.emit() is also defined there.
EventEmitter.prototype.addListener = function(type, listener) {
if ('function' !== typeof listener) {
throw new Error('addListener only takes instances of Function');
}
if (!this._events) this._events = {};
// To avoid recursion in the case that type == "newListeners"! Before
// adding it to the listeners, first emit "newListeners".
this.emit('newListener', type, listener);
if (!this._events[type]) {
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
} else if (isArray(this._events[type])) {
// Check for listener leak
if (!this._events[type].warned) {
var m;
if (this._events.maxListeners !== undefined) {
m = this._events.maxListeners;
} else {
m = defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
console.trace();
}
}
// If we've already got an array, just append.
this._events[type].push(listener);
} else {
// Adding the second element, need to change to array.
this._events[type] = [this._events[type], listener];
}
return this;
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.once = function(type, listener) {
var self = this;
self.on(type, function g() {
self.removeListener(type, g);
listener.apply(this, arguments);
});
return this;
};
EventEmitter.prototype.removeListener = function(type, listener) {
if ('function' !== typeof listener) {
throw new Error('removeListener only takes instances of Function');
}
// does not use listeners(), so no side effect of creating _events[type]
if (!this._events || !this._events[type]) return this;
var list = this._events[type];
if (isArray(list)) {
var i = list.indexOf(listener);
if (i < 0) return this;
list.splice(i, 1);
if (list.length == 0)
delete this._events[type];
} else if (this._events[type] === listener) {
delete this._events[type];
}
return this;
};
EventEmitter.prototype.removeAllListeners = function(type) {
// does not use listeners(), so no side effect of creating _events[type]
if (type && this._events && this._events[type]) this._events[type] = null;
return this;
};
EventEmitter.prototype.listeners = function(type) {
if (!this._events) this._events = {};
if (!this._events[type]) this._events[type] = [];
if (!isArray(this._events[type])) {
this._events[type] = [this._events[type]];
}
return this._events[type];
};
});
require.define("/node_modules/sprintf/package.json", function (require, module, exports, __dirname, __filename) {
module.exports = {"main":"./lib/sprintf"}
});
require.define("/node_modules/sprintf/lib/sprintf.js", function (require, module, exports, __dirname, __filename) {
/**
sprintf() for JavaScript 0.7-beta1
http://www.diveintojavascript.com/projects/javascript-sprintf
Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of sprintf() for JavaScript nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Changelog:
2010.11.07 - 0.7-beta1-node
- converted it to a node.js compatible module
2010.09.06 - 0.7-beta1
- features: vsprintf, support for named placeholders
- enhancements: format cache, reduced global namespace pollution
2010.05.22 - 0.6:
- reverted to 0.4 and fixed the bug regarding the sign of the number 0
Note:
Thanks to Raphael Pigulla <raph (at] n3rd [dot) org> (http://www.n3rd.org/)
who warned me about a bug in 0.5, I discovered that the last update was
a regress. I appologize for that.
2010.05.09 - 0.5:
- bug fix: 0 is now preceeded with a + sign
- bug fix: the sign was not at the right position on padded results (Kamal Abdali)
- switched from GPL to BSD license
2007.10.21 - 0.4:
- unit test and patch (David Baird)
2007.09.17 - 0.3:
- bug fix: no longer throws exception on empty paramenters (Hans Pufal)
2007.09.11 - 0.2:
- feature: added argument swapping
2007.04.03 - 0.1:
- initial release
**/
var sprintf = (function() {
function get_type(variable) {
return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
}
function str_repeat(input, multiplier) {
for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
return output.join('');
}
var str_format = function() {
if (!str_format.cache.hasOwnProperty(arguments[0])) {
str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
}
return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
};
str_format.format = function(parse_tree, argv) {
var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
for (i = 0; i < tree_length; i++) {
node_type = get_type(parse_tree[i]);
if (node_type === 'string') {
output.push(parse_tree[i]);
}
else if (node_type === 'array') {
match = parse_tree[i]; // convenience purposes only
if (match[2]) { // keyword argument
arg = argv[cursor];
for (k = 0; k < match[2].length; k++) {
if (!arg.hasOwnProperty(match[2][k])) {
throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
}
arg = arg[match[2][k]];
}
}
else if (match[1]) { // positional argument (explicit)
arg = argv[match[1]];
}
else { // positional argument (implicit)
arg = argv[cursor++];
}
if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
}
switch (match[8]) {
case 'b': arg = arg.toString(2); break;
case 'c': arg = String.fromCharCode(arg); break;
case 'd': arg = parseInt(arg, 10); break;
case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
case 'o': arg = arg.toString(8); break;
case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
case 'u': arg = Math.abs(arg); break;
case 'x': arg = arg.toString(16); break;
case 'X': arg = arg.toString(16).toUpperCase(); break;
}
arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
pad_length = match[6] - String(arg).length;
pad = match[6] ? str_repeat(pad_character, pad_length) : '';
output.push(match[5] ? arg + pad : pad + arg);
}
}
return output.join('');
};
str_format.cache = {};
str_format.parse = function(fmt) {
var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
while (_fmt) {
if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
parse_tree.push(match[0]);
}
else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
parse_tree.push('%');
}
else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
if (match[2]) {
arg_names |= 1;
var field_list = [], replacement_field = match[2], field_match = [];
if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
field_list.push(field_match[1]);
while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
field_list.push(field_match[1]);
}
else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
field_list.push(field_match[1]);
}
else {
throw('[sprintf] huh?');
}
}
}
else {
throw('[sprintf] huh?');
}
match[2] = field_list;
}
else {
arg_names |= 2;
}
if (arg_names === 3) {
throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
}
parse_tree.push(match);
}
else {
throw('[sprintf] huh?');
}
_fmt = _fmt.substring(match[0].length);
}
return parse_tree;
};
return str_format;
})();
var vsprintf = function(fmt, argv) {
argv.unshift(fmt);
return sprintf.apply(null, argv);
};
exports.sprintf = sprintf;
exports.vsprintf = vsprintf;
});
require.define("/shred/response.js", function (require, module, exports, __dirname, __filename) {
// The `Response object` encapsulates a Node.js HTTP response.
var Content = require("./content")
, HeaderMixins = require("./mixins/headers")
, CookieJarLib = require( "cookiejar" )
, Cookie = CookieJarLib.Cookie
;
// Browser doesn't have zlib.
var zlib = null;
try {
zlib = require('zlib');
} catch (e) {
console.warn("no zlib library");
}
// Iconv doesn't work in browser
var Iconv = null;
try {
Iconv = require('iconv-lite');
} catch (e) {
console.warn("no iconv library");
}
// Construct a `Response` object. You should never have to do this directly. The
// `Request` object handles this, getting the raw response object and passing it
// in here, along with the request. The callback allows us to stream the response
// and then use the callback to let the request know when it's ready.
var Response = function(raw, request, callback) {
var response = this;
this._raw = raw;
// The `._setHeaders` method is "private"; you can't otherwise set headers on
// the response.
this._setHeaders.call(this,raw.headers);
// store any cookies
if (request.cookieJar && this.getHeader('set-cookie')) {
var cookieStrings = this.getHeader('set-cookie');
var cookieObjs = []
, cookie;
for (var i = 0; i < cookieStrings.length; i++) {
var cookieString = cookieStrings[i];
if (!cookieString) {
continue;
}
if (!cookieString.match(/domain\=/i)) {
cookieString += '; domain=' + request.host;
}
if (!cookieString.match(/path\=/i)) {
cookieString += '; path=' + request.path;
}
try {
cookie = new Cookie(cookieString);
if (cookie) {
cookieObjs.push(cookie);
}
} catch (e) {
console.warn("Tried to set bad cookie: " + cookieString);
}
}
request.cookieJar.setCookies(cookieObjs);
}
this.request = request;
this.client = request.client;
this.log = this.request.log;
// Stream the response content entity and fire the callback when we're done.
// Store the incoming data in a array of Buffers which we concatinate into one
// buffer at the end. We need to use buffers instead of strings here in order
// to preserve binary data.
var chunkBuffers = [];
var dataLength = 0;
raw.on("data", function(chunk) {
chunkBuffers.push(chunk);
dataLength += chunk.length;
});
raw.on("end", function() {
var body;
if (typeof Buffer === 'undefined') {
// Just concatinate into a string
body = chunkBuffers.join('');
} else {
// Initialize new buffer and add the chunks one-at-a-time.
body = new Buffer(dataLength);
for (var i = 0, pos = 0; i < chunkBuffers.length; i++) {
chunkBuffers[i].copy(body, pos);
pos += chunkBuffers[i].length;
}
}
var setBodyAndFinish = function (body) {
response._body = new Content({
body: body,
type: response.getHeader("Content-Type")
});
callback(response);
}
if (zlib && response.getHeader("Content-Encoding") === 'gzip'){
zlib.gunzip(body, function (err, gunzippedBody) {
if (Iconv && response.request.encoding){
body = Iconv.fromEncoding(gunzippedBody,response.request.encoding);
} else {
body = gunzippedBody.toString();
}
setBodyAndFinish(body);
})
}
else{
if (response.request.encoding){
body = Iconv.fromEncoding(body,response.request.encoding);
}
setBodyAndFinish(body);
}
});
};
// The `Response` object can be pretty overwhelming to view using the built-in
// Node.js inspect method. We want to make it a bit more manageable. This
// probably goes [too far in the other
// direction](https://github.com/spire-io/shred/issues/2).
Response.prototype = {
inspect: function() {
var response = this;
var headers = this.format_headers();
var summary = ["<Shred Response> ", response.status].join(" ")
return [ summary, "- Headers:", headers].join("\n");
},
format_headers: function () {
var array = []
var headers = this._headers
for (var key in headers) {
if (headers.hasOwnProperty(key)) {
var value = headers[key]
array.push("\t" + key + ": " + value);
}
}
return array.join("\n");
}
};
// `Response` object properties, all of which are read-only:
Object.defineProperties(Response.prototype, {
// - **status**. The HTTP status code for the response.
status: {
get: function() { return this._raw.statusCode; },
enumerable: true
},
// - **content**. The HTTP content entity, if any. Provided as a [content
// object](./content.html), which will attempt to convert the entity based upon
// the `content-type` header. The converted value is available as
// `content.data`. The original raw content entity is available as
// `content.body`.
body: {
get: function() { return this._body; }
},
content: {
get: function() { return this.body; },
enumerable: true
},
// - **isRedirect**. Is the response a redirect? These are responses with 3xx
// status and a `Location` header.
isRedirect: {
get: function() {
return (this.status>299
&&this.status<400
&&this.getHeader("Location"));
},
enumerable: true
},
// - **isError**. Is the response an error? These are responses with status of
// 400 or greater.
isError: {
get: function() {
return (this.status === 0 || this.status > 399)
},
enumerable: true
}
});
// Add in the [getters for accessing the normalized headers](./headers.js).
HeaderMixins.getters(Response);
HeaderMixins.privateSetters(Response);
// Work around Mozilla bug #608735 [https://bugzil.la/608735], which causes
// getAllResponseHeaders() to return {} if the response is a CORS request.
// xhr.getHeader still works correctly.
var getHeader = Response.prototype.getHeader;
Response.prototype.getHeader = function (name) {
return (getHeader.call(this,name) ||
(typeof this._raw.getHeader === 'function' && this._raw.getHeader(name)));
};
module.exports = Response;
});
require.define("/shred/content.js", function (require, module, exports, __dirname, __filename) {
// The purpose of the `Content` object is to abstract away the data conversions
// to and from raw content entities as strings. For example, you want to be able
// to pass in a Javascript object and have it be automatically converted into a
// JSON string if the `content-type` is set to a JSON-based media type.
// Conversely, you want to be able to transparently get back a Javascript object
// in the response if the `content-type` is a JSON-based media-type.
// One limitation of the current implementation is that it [assumes the `charset` is UTF-8](https://github.com/spire-io/shred/issues/5).
// The `Content` constructor takes an options object, which *must* have either a
// `body` or `data` property and *may* have a `type` property indicating the
// media type. If there is no `type` attribute, a default will be inferred.
var Content = function(options) {
this.body = options.body;
this.data = options.data;
this.type = options.type;
};
Content.prototype = {
// Treat `toString()` as asking for the `content.body`. That is, the raw content entity.
//
// toString: function() { return this.body; }
//
// Commented out, but I've forgotten why. :/
};
// `Content` objects have the following attributes:
Object.defineProperties(Content.prototype,{
// - **type**. Typically accessed as `content.type`, reflects the `content-type`
// header associated with the request or response. If not passed as an options
// to the constructor or set explicitly, it will infer the type the `data`
// attribute, if possible, and, failing that, will default to `text/plain`.
type: {
get: function() {
if (this._type) {
return this._type;
} else {
if (this._data) {
switch(typeof this._data) {
case "string": return "text/plain";
case "object": return "application/json";
}
}
}
return "text/plain";
},
set: function(value) {
this._type = value;
return this;
},
enumerable: true
},
// - **data**. Typically accessed as `content.data`, reflects the content entity
// converted into Javascript data. This can be a string, if the `type` is, say,
// `text/plain`, but can also be a Javascript object. The conversion applied is
// based on the `processor` attribute. The `data` attribute can also be set
// directly, in which case the conversion will be done the other way, to infer
// the `body` attribute.
data: {
get: function() {
if (this._body) {
return this.processor.parser(this._body);
} else {
return this._data;
}
},
set: function(data) {
if (this._body&&data) Errors.setDataWithBody(this);
this._data = data;
return this;
},
enumerable: true
},
// - **body**. Typically accessed as `content.body`, reflects the content entity
// as a UTF-8 string. It is the mirror of the `data` attribute. If you set the
// `data` attribute, the `body` attribute will be inferred and vice-versa. If
// you attempt to set both, an exception is raised.
body: {
get: function() {
if (this._data) {
return this.processor.stringify(this._data);
} else {
return this.processor.stringify(this._body);
}
},
set: function(body) {
if (this._data&&body) Errors.setBodyWithData(this);
this._body = body;
return this;
},
enumerable: true
},
// - **processor**. The functions that will be used to convert to/from `data` and
// `body` attributes. You can add processors. The two that are built-in are for
// `text/plain`, which is basically an identity transformation and
// `application/json` and other JSON-based media types (including custom media
// types with `+json`). You can add your own processors. See below.
processor: {
get: function() {
var processor = Content.processors[this.type];
if (processor) {
return processor;
} else {
// Return the first processor that matches any part of the
// content type. ex: application/vnd.foobar.baz+json will match json.
var main = this.type.split(";")[0];
var parts = main.split(/\+|\//);
for (var i=0, l=parts.length; i < l; i++) {
processor = Content.processors[parts[i]]
}
return processor || {parser:identity,stringify:toString};
}
},
enumerable: true
},
// - **length**. Typically accessed as `content.length`, returns the length in
// bytes of the raw content entity.
length: {
get: function() {
if (typeof Buffer !== 'undefined') {
return Buffer.byteLength(this.body);
}
return this.body.length;
}
}
});
Content.processors = {};
// The `registerProcessor` function allows you to add your own processors to
// convert content entities. Each processor consists of a Javascript object with
// two properties:
// - **parser**. The function used to parse a raw content entity and convert it
// into a Javascript data type.
// - **stringify**. The function used to convert a Javascript data type into a
// raw content entity.
Content.registerProcessor = function(types,processor) {
// You can pass an array of types that will trigger this processor, or just one.
// We determine the array via duck-typing here.
if (types.forEach) {
types.forEach(function(type) {
Content.processors[type] = processor;
});
} else {
// If you didn't pass an array, we just use what you pass in.
Content.processors[types] = processor;
}
};
// Register the identity processor, which is used for text-based media types.
var identity = function(x) { return x; }
, toString = function(x) { return x.toString(); }
Content.registerProcessor(
["text/html","text/plain","text"],
{ parser: identity, stringify: toString });
// Register the JSON processor, which is used for JSON-based media types.
Content.registerProcessor(
["application/json; charset=utf-8","application/json","json"],
{
parser: function(string) {
return JSON.parse(string);
},
stringify: function(data) {
return JSON.stringify(data); }});
// Error functions are defined separately here in an attempt to make the code
// easier to read.
var Errors = {
setDataWithBody: function(object) {
throw new Error("Attempt to set data attribute of a content object " +
"when the body attributes was already set.");
},
setBodyWithData: function(object) {
throw new Error("Attempt to set body attribute of a content object " +
"when the data attributes was already set.");
}
}
module.exports = Content;
});
require.define("/shred/mixins/headers.js", function (require, module, exports, __dirname, __filename) {
// The header mixins allow you to add HTTP header support to any object. This
// might seem pointless: why not simply use a hash? The main reason is that, per
// the [HTTP spec](http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2),
// headers are case-insensitive. So, for example, `content-type` is the same as
// `CONTENT-TYPE` which is the same as `Content-Type`. Since there is no way to
// overload the index operator in Javascript, using a hash to represent the
// headers means it's possible to have two conflicting values for a single
// header.
//
// The solution to this is to provide explicit methods to set or get headers.
// This also has the benefit of allowing us to introduce additional variations,
// including snake case, which we automatically convert to what Matthew King has
// dubbed "corset case" - the hyphen-separated names with initial caps:
// `Content-Type`. We use corset-case just in case we're dealing with servers
// that haven't properly implemented the spec.
// Convert headers to corset-case. **Example:** `CONTENT-TYPE` will be converted
// to `Content-Type`.
var corsetCase = function(string) {
return string.toLowerCase()
//.replace("_","-")
.replace(/(^|-)(\w)/g,
function(s) { return s.toUpperCase(); });
};
// We suspect that `initializeHeaders` was once more complicated ...
var initializeHeaders = function(object) {
return {};
};
// Access the `_headers` property using lazy initialization. **Warning:** If you
// mix this into an object that is using the `_headers` property already, you're
// going to have trouble.
var $H = function(object) {
return object._headers||(object._headers=initializeHeaders(object));
};
// Hide the implementations as private functions, separate from how we expose them.
// The "real" `getHeader` function: get the header after normalizing the name.
var getHeader = function(object,name) {
return $H(object)[corsetCase(name)];
};
// The "real" `getHeader` function: get one or more headers, or all of them
// if you don't ask for any specifics.
var getHeaders = function(object,names) {
var keys = (names && names.length>0) ? names : Object.keys($H(object));
var hash = keys.reduce(function(hash,key) {
hash[key] = getHeader(object,key);
return hash;
},{});
// Freeze the resulting hash so you don't mistakenly think you're modifying
// the real headers.
Object.freeze(hash);
return hash;
};
// The "real" `setHeader` function: set a header, after normalizing the name.
var setHeader = function(object,name,value) {
$H(object)[corsetCase(name)] = value;
return object;
};
// The "real" `setHeaders` function: set multiple headers based on a hash.
var setHeaders = function(object,hash) {
for( var key in hash ) { setHeader(object,key,hash[key]); };
return this;
};
// Here's where we actually bind the functionality to an object. These mixins work by
// exposing mixin functions. Each function mixes in a specific batch of features.
module.exports = {
// Add getters.
getters: function(constructor) {
constructor.prototype.getHeader = function(name) { return getHeader(this,name); };
constructor.prototype.getHeaders = function() { return getHeaders(this,arguments); };
},
// Add setters but as "private" methods.
privateSetters: function(constructor) {
constructor.prototype._setHeader = function(key,value) { return setHeader(this,key,value); };
constructor.prototype._setHeaders = function(hash) { return setHeaders(this,hash); };
},
// Add setters.
setters: function(constructor) {
constructor.prototype.setHeader = function(key,value) { return setHeader(this,key,value); };
constructor.prototype.setHeaders = function(hash) { return setHeaders(this,hash); };
},
// Add both getters and setters.
gettersAndSetters: function(constructor) {
constructor.prototype.getHeader = function(name) { return getHeader(this,name); };
constructor.prototype.getHeaders = function() { return getHeaders(this,arguments); };
constructor.prototype.setHeader = function(key,value) { return setHeader(this,key,value); };
constructor.prototype.setHeaders = function(hash) { return setHeaders(this,hash); };
},
};
});
require.define("/node_modules/iconv-lite/package.json", function (require, module, exports, __dirname, __filename) {
module.exports = {}
});
require.define("/node_modules/iconv-lite/index.js", function (require, module, exports, __dirname, __filename) {
// Module exports
var iconv = module.exports = {
toEncoding: function(str, encoding) {
return iconv.getCodec(encoding).toEncoding(str);
},
fromEncoding: function(buf, encoding) {
return iconv.getCodec(encoding).fromEncoding(buf);
},
defaultCharUnicode: '<27>',
defaultCharSingleByte: '?',
// Get correct codec for given encoding.
getCodec: function(encoding) {
var enc = encoding || "utf8";
var codecOptions = undefined;
while (1) {
if (getType(enc) === "String")
enc = enc.replace(/[- ]/g, "").toLowerCase();
var codec = iconv.encodings[enc];
var type = getType(codec);
if (type === "String") {
// Link to other encoding.
codecOptions = {originalEncoding: enc};
enc = codec;
}
else if (type === "Object" && codec.type != undefined) {
// Options for other encoding.
codecOptions = codec;
enc = codec.type;
}
else if (type === "Function")
// Codec itself.
return codec(codecOptions);
else
throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')");
}
},
// Define basic encodings
encodings: {
internal: function(options) {
return {
toEncoding: function(str) {
return new Buffer(ensureString(str), options.originalEncoding);
},
fromEncoding: function(buf) {
return ensureBuffer(buf).toString(options.originalEncoding);
}
};
},
utf8: "internal",
ucs2: "internal",
binary: "internal",
ascii: "internal",
base64: "internal",
// Codepage single-byte encodings.
singlebyte: function(options) {
// Prepare chars if needed
if (!options.chars || (options.chars.length !== 128 && options.chars.length !== 256))
throw new Error("Encoding '"+options.type+"' has incorrect 'chars' (must be of len 128 or 256)");
if (options.chars.length === 128)
options.chars = asciiString + options.chars;
if (!options.charsBuf) {
options.charsBuf = new Buffer(options.chars, 'ucs2');
}
if (!options.revCharsBuf) {
options.revCharsBuf = new Buffer(65536);
var defChar = iconv.defaultCharSingleByte.charCodeAt(0);
for (var i = 0; i < options.revCharsBuf.length; i++)
options.revCharsBuf[i] = defChar;
for (var i = 0; i < options.chars.length; i++)
options.revCharsBuf[options.chars.charCodeAt(i)] = i;
}
return {
toEncoding: function(str) {
str = ensureString(str);
var buf = new Buffer(str.length);
var revCharsBuf = options.revCharsBuf;
for (var i = 0; i < str.length; i++)
buf[i] = revCharsBuf[str.charCodeAt(i)];
return buf;
},
fromEncoding: function(buf) {
buf = ensureBuffer(buf);
// Strings are immutable in JS -> we use ucs2 buffer to speed up computations.
var charsBuf = options.charsBuf;
var newBuf = new Buffer(buf.length*2);
var idx1 = 0, idx2 = 0;
for (var i = 0, _len = buf.length; i < _len; i++) {
idx1 = buf[i]*2; idx2 = i*2;
newBuf[idx2] = charsBuf[idx1];
newBuf[idx2+1] = charsBuf[idx1+1];
}
return newBuf.toString('ucs2');
}
};
},
// Codepage double-byte encodings.
table: function(options) {
var table = options.table, key, revCharsTable = options.revCharsTable;
if (!table) {
throw new Error("Encoding '" + options.type +"' has incorect 'table' option");
}
if(!revCharsTable) {
revCharsTable = options.revCharsTable = {};
for (key in table) {
revCharsTable[table[key]] = parseInt(key);
}
}
return {
toEncoding: function(str) {
str = ensureString(str);
var strLen = str.length;
var bufLen = strLen;
for (var i = 0; i < strLen; i++)
if (str.charCodeAt(i) >> 7)
bufLen++;
var newBuf = new Buffer(bufLen), gbkcode, unicode,
defaultChar = revCharsTable[iconv.defaultCharUnicode.charCodeAt(0)];
for (var i = 0, j = 0; i < strLen; i++) {
unicode = str.charCodeAt(i);
if (unicode >> 7) {
gbkcode = revCharsTable[unicode] || defaultChar;
newBuf[j++] = gbkcode >> 8; //high byte;
newBuf[j++] = gbkcode & 0xFF; //low byte
} else {//ascii
newBuf[j++] = unicode;
}
}
return newBuf;
},
fromEncoding: function(buf) {
buf = ensureBuffer(buf);
var bufLen = buf.length, strLen = 0;
for (var i = 0; i < bufLen; i++) {
strLen++;
if (buf[i] & 0x80) //the high bit is 1, so this byte is gbkcode's high byte.skip next byte
i++;
}
var newBuf = new Buffer(strLen*2), unicode, gbkcode,
defaultChar = iconv.defaultCharUnicode.charCodeAt(0);
for (var i = 0, j = 0; i < bufLen; i++, j+=2) {
gbkcode = buf[i];
if (gbkcode & 0x80) {
gbkcode = (gbkcode << 8) + buf[++i];
unicode = table[gbkcode] || defaultChar;
} else {
unicode = gbkcode;
}
newBuf[j] = unicode & 0xFF; //low byte
newBuf[j+1] = unicode >> 8; //high byte
}
return newBuf.toString('ucs2');
}
}
}
}
};
// Add aliases to convert functions
iconv.encode = iconv.toEncoding;
iconv.decode = iconv.fromEncoding;
// Load other encodings from files in /encodings dir.
var encodingsDir = __dirname+"/encodings/",
fs = require('fs');
fs.readdirSync(encodingsDir).forEach(function(file) {
if(fs.statSync(encodingsDir + file).isDirectory()) return;
var encodings = require(encodingsDir + file)
for (var key in encodings)
iconv.encodings[key] = encodings[key]
});
// Utilities
var asciiString = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f'+
' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f';
var ensureBuffer = function(buf) {
buf = buf || new Buffer(0);
return (buf instanceof Buffer) ? buf : new Buffer(buf.toString(), "utf8");
}
var ensureString = function(str) {
str = str || "";
return (str instanceof String) ? str : str.toString((str instanceof Buffer) ? 'utf8' : undefined);
}
var getType = function(obj) {
return Object.prototype.toString.call(obj).slice(8, -1);
}
});
require.define("/node_modules/http-browserify/package.json", function (require, module, exports, __dirname, __filename) {
module.exports = {"main":"index.js","browserify":"browser.js"}
});
require.define("/node_modules/http-browserify/browser.js", function (require, module, exports, __dirname, __filename) {
var http = module.exports;
var EventEmitter = require('events').EventEmitter;
var Request = require('./lib/request');
http.request = function (params, cb) {
if (!params) params = {};
if (!params.host) params.host = window.location.host.split(':')[0];
if (!params.port) params.port = window.location.port;
var req = new Request(new xhrHttp, params);
if (cb) req.on('response', cb);
return req;
};
http.get = function (params, cb) {
params.method = 'GET';
var req = http.request(params, cb);
req.end();
return req;
};
var xhrHttp = (function () {
if (typeof window === 'undefined') {
throw new Error('no window object present');
}
else if (window.XMLHttpRequest) {
return window.XMLHttpRequest;
}
else if (window.ActiveXObject) {
var axs = [
'Msxml2.XMLHTTP.6.0',
'Msxml2.XMLHTTP.3.0',
'Microsoft.XMLHTTP'
];
for (var i = 0; i < axs.length; i++) {
try {
var ax = new(window.ActiveXObject)(axs[i]);
return function () {
if (ax) {
var ax_ = ax;
ax = null;
return ax_;
}
else {
return new(window.ActiveXObject)(axs[i]);
}
};
}
catch (e) {}
}
throw new Error('ajax not supported in this browser')
}
else {
throw new Error('ajax not supported in this browser');
}
})();
http.STATUS_CODES = {
100 : 'Continue',
101 : 'Switching Protocols',
102 : 'Processing', // RFC 2518, obsoleted by RFC 4918
200 : 'OK',
201 : 'Created',
202 : 'Accepted',
203 : 'Non-Authoritative Information',
204 : 'No Content',
205 : 'Reset Content',
206 : 'Partial Content',
207 : 'Multi-Status', // RFC 4918
300 : 'Multiple Choices',
301 : 'Moved Permanently',
302 : 'Moved Temporarily',
303 : 'See Other',
304 : 'Not Modified',
305 : 'Use Proxy',
307 : 'Temporary Redirect',
400 : 'Bad Request',
401 : 'Unauthorized',
402 : 'Payment Required',
403 : 'Forbidden',
404 : 'Not Found',
405 : 'Method Not Allowed',
406 : 'Not Acceptable',
407 : 'Proxy Authentication Required',
408 : 'Request Time-out',
409 : 'Conflict',
410 : 'Gone',
411 : 'Length Required',
412 : 'Precondition Failed',
413 : 'Request Entity Too Large',
414 : 'Request-URI Too Large',
415 : 'Unsupported Media Type',
416 : 'Requested Range Not Satisfiable',
417 : 'Expectation Failed',
418 : 'I\'m a teapot', // RFC 2324
422 : 'Unprocessable Entity', // RFC 4918
423 : 'Locked', // RFC 4918
424 : 'Failed Dependency', // RFC 4918
425 : 'Unordered Collection', // RFC 4918
426 : 'Upgrade Required', // RFC 2817
500 : 'Internal Server Error',
501 : 'Not Implemented',
502 : 'Bad Gateway',
503 : 'Service Unavailable',
504 : 'Gateway Time-out',
505 : 'HTTP Version not supported',
506 : 'Variant Also Negotiates', // RFC 2295
507 : 'Insufficient Storage', // RFC 4918
509 : 'Bandwidth Limit Exceeded',
510 : 'Not Extended' // RFC 2774
};
});
require.define("/node_modules/http-browserify/lib/request.js", function (require, module, exports, __dirname, __filename) {
var EventEmitter = require('events').EventEmitter;
var Response = require('./response');
var isSafeHeader = require('./isSafeHeader');
var Request = module.exports = function (xhr, params) {
var self = this;
self.xhr = xhr;
self.body = '';
var uri = params.host + ':' + params.port + (params.path || '/');
xhr.open(
params.method || 'GET',
(params.scheme || 'http') + '://' + uri,
true
);
if (params.headers) {
Object.keys(params.headers).forEach(function (key) {
if (!isSafeHeader(key)) return;
var value = params.headers[key];
if (Array.isArray(value)) {
value.forEach(function (v) {
xhr.setRequestHeader(key, v);
});
}
else xhr.setRequestHeader(key, value)
});
}
var res = new Response(xhr);
res.on('ready', function () {
self.emit('response', res);
});
xhr.onreadystatechange = function () {
res.handle(xhr);
};
};
Request.prototype = new EventEmitter;
Request.prototype.setHeader = function (key, value) {
if ((Array.isArray && Array.isArray(value))
|| value instanceof Array) {
for (var i = 0; i < value.length; i++) {
this.xhr.setRequestHeader(key, value[i]);
}
}
else {
this.xhr.setRequestHeader(key, value);
}
};
Request.prototype.write = function (s) {
this.body += s;
};
Request.prototype.end = function (s) {
if (s !== undefined) this.write(s);
this.xhr.send(this.body);
};
});
require.define("/node_modules/http-browserify/lib/response.js", function (require, module, exports, __dirname, __filename) {
var EventEmitter = require('events').EventEmitter;
var isSafeHeader = require('./isSafeHeader');
var Response = module.exports = function (xhr) {
this.xhr = xhr;
this.offset = 0;
};
Response.prototype = new EventEmitter;
var capable = {
streaming : true,
status2 : true
};
function parseHeaders (xhr) {
var lines = xhr.getAllResponseHeaders().split(/\r?\n/);
var headers = {};
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (line === '') continue;
var m = line.match(/^([^:]+):\s*(.*)/);
if (m) {
var key = m[1].toLowerCase(), value = m[2];
if (headers[key] !== undefined) {
if ((Array.isArray && Array.isArray(headers[key]))
|| headers[key] instanceof Array) {
headers[key].push(value);
}
else {
headers[key] = [ headers[key], value ];
}
}
else {
headers[key] = value;
}
}
else {
headers[line] = true;
}
}
return headers;
}
Response.prototype.getHeader = function (key) {
var header = this.headers ? this.headers[key.toLowerCase()] : null;
if (header) return header;
// Work around Mozilla bug #608735 [https://bugzil.la/608735], which causes
// getAllResponseHeaders() to return {} if the response is a CORS request.
// xhr.getHeader still works correctly.
if (isSafeHeader(key)) {
return this.xhr.getResponseHeader(key);
}
return null;
};
Response.prototype.handle = function () {
var xhr = this.xhr;
if (xhr.readyState === 2 && capable.status2) {
try {
this.statusCode = xhr.status;
this.headers = parseHeaders(xhr);
}
catch (err) {
capable.status2 = false;
}
if (capable.status2) {
this.emit('ready');
}
}
else if (capable.streaming && xhr.readyState === 3) {
try {
if (!this.statusCode) {
this.statusCode = xhr.status;
this.headers = parseHeaders(xhr);
this.emit('ready');
}
}
catch (err) {}
try {
this.write();
}
catch (err) {
capable.streaming = false;
}
}
else if (xhr.readyState === 4) {
if (!this.statusCode) {
this.statusCode = xhr.status;
this.emit('ready');
}
this.write();
if (xhr.error) {
this.emit('error', xhr.responseText);
}
else this.emit('end');
}
};
Response.prototype.write = function () {
var xhr = this.xhr;
if (xhr.responseText.length > this.offset) {
this.emit('data', xhr.responseText.slice(this.offset));
this.offset = xhr.responseText.length;
}
};
});
require.define("/node_modules/http-browserify/lib/isSafeHeader.js", function (require, module, exports, __dirname, __filename) {
// Taken from http://dxr.mozilla.org/mozilla/mozilla-central/content/base/src/nsXMLHttpRequest.cpp.html
var unsafeHeaders = [
"accept-charset",
"accept-encoding",
"access-control-request-headers",
"access-control-request-method",
"connection",
"content-length",
"cookie",
"cookie2",
"content-transfer-encoding",
"date",
"expect",
"host",
"keep-alive",
"origin",
"referer",
"set-cookie",
"te",
"trailer",
"transfer-encoding",
"upgrade",
"user-agent",
"via"
];
module.exports = function (headerName) {
if (!headerName) return false;
return (unsafeHeaders.indexOf(headerName.toLowerCase()) === -1)
};
});
require.alias("http-browserify", "/node_modules/http");
require.alias("http-browserify", "/node_modules/https");