diff options
author | Matthew Hodgson <matthew@matrix.org> | 2014-11-11 21:10:36 +0200 |
---|---|---|
committer | Matthew Hodgson <matthew@matrix.org> | 2014-11-12 00:18:25 +0200 |
commit | 774cff3c724c288172dbebf206dcd21d8dfdb011 (patch) | |
tree | 8952af0c109320e4950e3da8e1c517f97a877f7b /docs/client-server/web/files/shred.bundle.js | |
parent | move stuff out of implementation-notes - /everything/ here should be implemen... (diff) | |
download | synapse-774cff3c724c288172dbebf206dcd21d8dfdb011.tar.xz |
move swagger impl to matrix-doc
Diffstat (limited to 'docs/client-server/web/files/shred.bundle.js')
-rw-r--r-- | docs/client-server/web/files/shred.bundle.js | 2765 |
1 files changed, 0 insertions, 2765 deletions
diff --git a/docs/client-server/web/files/shred.bundle.js b/docs/client-server/web/files/shred.bundle.js deleted file mode 100644 index 74d0816892..0000000000 --- a/docs/client-server/web/files/shred.bundle.js +++ /dev/null @@ -1,2765 +0,0 @@ -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: '�', - 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"); \ No newline at end of file |