2 * Copyright 2016 ZTE Corporation.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 var require = function (file, cwd) {
17 var resolved = require.resolve(file, cwd || '/');
18 var mod = require.modules[resolved];
19 if (!mod) throw new Error(
20 'Failed to resolve module ' + file + ', tried ' + resolved
22 var res = mod._cached ? mod._cached : mod();
28 require.extensions = [".js",".coffee"];
38 require.resolve = (function () {
39 return function (x, cwd) {
42 if (require._core[x]) return x;
43 var path = require.modules.path();
46 if (x.match(/^(?:\.\.?\/|\/)/)) {
47 var m = loadAsFileSync(path.resolve(y, x))
48 || loadAsDirectorySync(path.resolve(y, x));
52 var n = loadNodeModulesSync(x, y);
55 throw new Error("Cannot find module '" + x + "'");
57 function loadAsFileSync (x) {
58 if (require.modules[x]) {
62 for (var i = 0; i < require.extensions.length; i++) {
63 var ext = require.extensions[i];
64 if (require.modules[x + ext]) return x + ext;
68 function loadAsDirectorySync (x) {
69 x = x.replace(/\/+$/, '');
70 var pkgfile = x + '/package.json';
71 if (require.modules[pkgfile]) {
72 var pkg = require.modules[pkgfile]();
73 var b = pkg.browserify;
74 if (typeof b === 'object' && b.main) {
75 var m = loadAsFileSync(path.resolve(x, b.main));
78 else if (typeof b === 'string') {
79 var m = loadAsFileSync(path.resolve(x, b));
83 var m = loadAsFileSync(path.resolve(x, pkg.main));
88 return loadAsFileSync(x + '/index');
91 function loadNodeModulesSync (x, start) {
92 var dirs = nodeModulesPathsSync(start);
93 for (var i = 0; i < dirs.length; i++) {
95 var m = loadAsFileSync(dir + '/' + x);
97 var n = loadAsDirectorySync(dir + '/' + x);
101 var m = loadAsFileSync(x);
105 function nodeModulesPathsSync (start) {
107 if (start === '/') parts = [ '' ];
108 else parts = path.normalize(start).split('/');
111 for (var i = parts.length - 1; i >= 0; i--) {
112 if (parts[i] === 'node_modules') continue;
113 var dir = parts.slice(0, i + 1).join('/') + '/node_modules';
122 require.alias = function (from, to) {
123 var path = require.modules.path();
126 res = require.resolve(from + '/package.json', '/');
129 res = require.resolve(from, '/');
131 var basedir = path.dirname(res);
133 var keys = (Object.keys || function (obj) {
135 for (var key in obj) res.push(key)
139 for (var i = 0; i < keys.length; i++) {
141 if (key.slice(0, basedir.length + 1) === basedir + '/') {
142 var f = key.slice(basedir.length);
143 require.modules[to + f] = require.modules[basedir + f];
145 else if (key === basedir) {
146 require.modules[to] = require.modules[basedir];
151 require.define = function (filename, fn) {
152 var dirname = require._core[filename]
154 : require.modules.path().dirname(filename)
157 var require_ = function (file) {
158 return require(file, dirname)
160 require_.resolve = function (name) {
161 return require.resolve(name, dirname);
163 require_.modules = require.modules;
164 require_.define = require.define;
165 var module_ = { exports : {} };
167 require.modules[filename] = function () {
168 require.modules[filename]._cached = module_.exports;
177 require.modules[filename]._cached = module_.exports;
178 return module_.exports;
182 if (typeof process === 'undefined') process = {};
184 if (!process.nextTick) process.nextTick = (function () {
186 var canPost = typeof window !== 'undefined'
187 && window.postMessage && window.addEventListener
191 window.addEventListener('message', function (ev) {
192 if (ev.source === window && ev.data === 'browserify-tick') {
193 ev.stopPropagation();
194 if (queue.length > 0) {
195 var fn = queue.shift();
202 return function (fn) {
205 window.postMessage('browserify-tick', '*');
207 else setTimeout(fn, 0);
211 if (!process.title) process.title = 'browser';
213 if (!process.binding) process.binding = function (name) {
214 if (name === 'evals') return require('vm')
215 else throw new Error('No such module')
218 if (!process.cwd) process.cwd = function () { return '.' };
220 require.define("path", function (require, module, exports, __dirname, __filename) {
221 function filter (xs, fn) {
223 for (var i = 0; i < xs.length; i++) {
224 if (fn(xs[i], i, xs)) res.push(xs[i]);
229 // resolves . and .. elements in a path array with directory names there
230 // must be no slashes, empty elements, or device names (c:\) in the array
231 // (so also no leading and trailing slashes - it does not distinguish
232 // relative and absolute paths)
233 function normalizeArray(parts, allowAboveRoot) {
234 // if the path tries to go above the root, `up` ends up > 0
236 for (var i = parts.length; i >= 0; i--) {
240 } else if (last === '..') {
249 // if the path is allowed to go above the root, restore leading ..s
250 if (allowAboveRoot) {
259 // Regex to split a filename into [*, dir, basename, ext]
261 var splitPathRe = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/;
263 // path.resolve([from ...], to)
265 exports.resolve = function() {
266 var resolvedPath = '',
267 resolvedAbsolute = false;
269 for (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) {
274 // Skip empty and invalid entries
275 if (typeof path !== 'string' || !path) {
279 resolvedPath = path + '/' + resolvedPath;
280 resolvedAbsolute = path.charAt(0) === '/';
283 // At this point the path should be resolved to a full absolute path, but
284 // handle relative paths to be safe (might happen when process.cwd() fails)
286 // Normalize the path
287 resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
289 }), !resolvedAbsolute).join('/');
291 return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
294 // path.normalize(path)
296 exports.normalize = function(path) {
297 var isAbsolute = path.charAt(0) === '/',
298 trailingSlash = path.slice(-1) === '/';
300 // Normalize the path
301 path = normalizeArray(filter(path.split('/'), function(p) {
303 }), !isAbsolute).join('/');
305 if (!path && !isAbsolute) {
308 if (path && trailingSlash) {
312 return (isAbsolute ? '/' : '') + path;
317 exports.join = function() {
318 var paths = Array.prototype.slice.call(arguments, 0);
319 return exports.normalize(filter(paths, function(p, index) {
320 return p && typeof p === 'string';
325 exports.dirname = function(path) {
326 var dir = splitPathRe.exec(path)[1] || '';
327 var isWindows = false;
331 } else if (dir.length === 1 ||
332 (isWindows && dir.length <= 3 && dir.charAt(1) === ':')) {
333 // It is just a slash or a drive letter with a slash
336 // It is a full dirname, strip trailing slash
337 return dir.substring(0, dir.length - 1);
342 exports.basename = function(path, ext) {
343 var f = splitPathRe.exec(path)[2] || '';
344 // TODO: make this comparison case-insensitive on windows?
345 if (ext && f.substr(-1 * ext.length) === ext) {
346 f = f.substr(0, f.length - ext.length);
352 exports.extname = function(path) {
353 return splitPathRe.exec(path)[3] || '';
358 require.define("/shred.js", function (require, module, exports, __dirname, __filename) {
359 // Shred is an HTTP client library intended to simplify the use of Node's
360 // built-in HTTP library. In particular, we wanted to make it easier to interact
361 // with HTTP-based APIs.
363 // See the [examples](./examples.html) for more details.
365 // Ax is a nice logging library we wrote. You can use any logger, providing it
366 // has `info`, `warn`, `debug`, and `error` methods that take a string.
367 var Ax = require("ax")
368 , CookieJarLib = require( "cookiejar" )
369 , CookieJar = CookieJarLib.CookieJar
372 // Shred takes some options, including a logger and request defaults.
374 var Shred = function(options) {
375 options = (options||{});
376 this.agent = options.agent;
377 this.defaults = options.defaults||{};
378 this.log = options.logger||(new Ax({ level: "info" }));
379 this._sharedCookieJar = new CookieJar();
380 this.logCurl = options.logCurl || false;
383 // Most of the real work is done in the request and reponse classes.
385 Shred.Request = require("./shred/request");
386 Shred.Response = require("./shred/response");
388 // The `request` method kicks off a new request, instantiating a new `Request`
389 // object and passing along whatever default options we were given.
392 request: function(options) {
393 options.logger = this.log;
394 options.logCurl = options.logCurl || this.logCurl;
395 options.cookieJar = ( 'cookieJar' in options ) ? options.cookieJar : this._sharedCookieJar; // let them set cookieJar = null
396 options.agent = options.agent || this.agent;
397 // fill in default options
398 for (var key in this.defaults) {
399 if (this.defaults.hasOwnProperty(key) && !options[key]) {
400 options[key] = this.defaults[key]
403 return new Shred.Request(options);
407 // Define a bunch of convenience methods so that you don't have to include
408 // a `method` property in your request options.
410 "get put post delete".split(" ").forEach(function(method) {
411 Shred.prototype[method] = function(options) {
412 options.method = method;
413 return this.request(options);
418 module.exports = Shred;
422 require.define("/node_modules/ax/package.json", function (require, module, exports, __dirname, __filename) {
423 module.exports = {"main":"./lib/ax.js"}
426 require.define("/node_modules/ax/lib/ax.js", function (require, module, exports, __dirname, __filename) {
427 var inspect = require("util").inspect
432 // this is a quick-and-dirty logger. there are other nicer loggers out there
433 // but the ones i found were also somewhat involved. this one has a Ruby
434 // logger type interface
436 // we can easily replace this, provide the info, debug, etc. methods are the
437 // same. or, we can change Haiku to use a more standard node.js interface
439 var format = function(level,message) {
440 var debug = (level=="debug"||level=="error");
441 if (!message) { return message.toString(); }
442 if (typeof(message) == "object") {
443 if (message instanceof Error && debug) {
444 return message.stack;
446 return inspect(message);
449 return message.toString();
453 var noOp = function(message) { return this; }
454 var makeLogger = function(level,fn) {
455 return function(message) {
456 this.stream.write(this.format(level, message)+"\n");
461 var Logger = function(options) {
463 var options = options||{};
466 options.level = options.level || "info";
467 options.timestamp = options.timestamp || true;
468 options.prefix = options.prefix || "";
469 logger.options = options;
471 // Allows a prefix to be added to the message.
473 // var logger = new Ax({ module: 'Haiku' })
474 // logger.warn('this is going to be awesome!');
475 // //=> Haiku: this is going to be awesome!
477 if (logger.options.module){
478 logger.options.prefix = logger.options.module;
481 // Write to stderr or a file
482 if (logger.options.file){
483 logger.stream = fs.createWriteStream(logger.options.file, {"flags": "a"});
485 if(process.title === "node")
486 logger.stream = process.stderr;
487 else if(process.title === "browser")
488 logger.stream = function () {
489 // Work around weird console context issue: http://code.google.com/p/chromium/issues/detail?id=48662
490 return console[logger.options.level].apply(console, arguments);
494 switch(logger.options.level){
496 ['debug', 'info', 'warn'].forEach(function (level) {
497 logger[level] = Logger.writer(level);
500 ['info', 'warn'].forEach(function (level) {
501 logger[level] = Logger.writer(level);
504 logger.warn = Logger.writer('warn');
508 // Used to define logger methods
509 Logger.writer = function(level){
510 return function(message){
513 if(process.title === "node")
514 logger.stream.write(logger.format(level, message) + '\n');
515 else if(process.title === "browser")
516 logger.stream(logger.format(level, message) + '\n');
526 error: Logger.writer('error'),
527 format: function(level, message){
528 if (! message) return '';
531 , prefix = logger.options.prefix
532 , timestamp = logger.options.timestamp ? " " + (new Date().toISOString()) : ""
535 return (prefix + timestamp + ": " + message);
539 module.exports = Logger;
543 require.define("util", function (require, module, exports, __dirname, __filename) {
548 require.define("fs", function (require, module, exports, __dirname, __filename) {
549 // nothing to see here... no file methods for the browser
553 require.define("/node_modules/cookiejar/package.json", function (require, module, exports, __dirname, __filename) {
554 module.exports = {"main":"cookiejar.js"}
557 require.define("/node_modules/cookiejar/cookiejar.js", function (require, module, exports, __dirname, __filename) {
558 exports.CookieAccessInfo=CookieAccessInfo=function CookieAccessInfo(domain,path,secure,script) {
559 if(this instanceof CookieAccessInfo) {
560 this.domain=domain||undefined;
562 this.secure=!!secure;
563 this.script=!!script;
567 return new CookieAccessInfo(domain,path,secure,script)
571 exports.Cookie=Cookie=function Cookie(cookiestr) {
572 if(cookiestr instanceof Cookie) {
576 if(this instanceof Cookie) {
579 this.expiration_date = Infinity;
582 this.secure = false; //how to define?
583 this.noscript = false; //httponly
585 this.parse(cookiestr)
589 return new Cookie(cookiestr)
593 Cookie.prototype.toString = function toString() {
594 var str=[this.name+"="+this.value];
595 if(this.expiration_date !== Infinity) {
596 str.push("expires="+(new Date(this.expiration_date)).toGMTString());
599 str.push("domain="+this.domain);
602 str.push("path="+this.path);
608 str.push("httponly");
610 return str.join("; ");
613 Cookie.prototype.toValueString = function toValueString() {
614 return this.name+"="+this.value;
617 var cookie_str_splitter=/[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g
618 Cookie.prototype.parse = function parse(str) {
619 if(this instanceof Cookie) {
620 var parts=str.split(";")
621 , pair=parts[0].match(/([^=]+)=((?:.|\n)*)/)
627 for(var i=1;i<parts.length;i++) {
628 pair=parts[i].match(/([^=]+)(?:=((?:.|\n)*))?/)
629 , key=pair[1].trim().toLowerCase()
633 this.noscript = true;
636 this.expiration_date = value
637 ? Number(Date.parse(value))
658 return new Cookie().parse(str)
661 Cookie.prototype.matches = function matches(access_info) {
662 if(this.noscript && access_info.script
663 || this.secure && !access_info.secure
664 || !this.collidesWith(access_info)) {
670 Cookie.prototype.collidesWith = function collidesWith(access_info) {
671 if((this.path && !access_info.path) || (this.domain && !access_info.domain)) {
674 if(this.path && access_info.path.indexOf(this.path) !== 0) {
677 if (this.domain===access_info.domain) {
680 else if(this.domain && this.domain.charAt(0)===".")
682 var wildcard=access_info.domain.indexOf(this.domain.slice(1))
683 if(wildcard===-1 || wildcard!==access_info.domain.length-this.domain.length+1) {
687 else if(this.domain){
693 exports.CookieJar=CookieJar=function CookieJar() {
694 if(this instanceof CookieJar) {
695 var cookies = {} //name: [Cookie]
697 this.setCookie = function setCookie(cookie) {
698 cookie = Cookie(cookie);
699 //Delete the cookie if the set is past the current time
700 var remove = cookie.expiration_date <= Date.now();
701 if(cookie.name in cookies) {
702 var cookies_list = cookies[cookie.name];
703 for(var i=0;i<cookies_list.length;i++) {
704 var collidable_cookie = cookies_list[i];
705 if(collidable_cookie.collidesWith(cookie)) {
707 cookies_list.splice(i,1);
708 if(cookies_list.length===0) {
709 delete cookies[cookie.name]
714 return cookies_list[i]=cookie;
721 cookies_list.push(cookie);
728 return cookies[cookie.name]=[cookie];
732 this.getCookie = function getCookie(cookie_name,access_info) {
733 var cookies_list = cookies[cookie_name];
734 for(var i=0;i<cookies_list.length;i++) {
735 var cookie = cookies_list[i];
736 if(cookie.expiration_date <= Date.now()) {
737 if(cookies_list.length===0) {
738 delete cookies[cookie.name]
742 if(cookie.matches(access_info)) {
747 //returns a list of cookies
748 this.getCookies = function getCookies(access_info) {
750 for(var cookie_name in cookies) {
751 var cookie=this.getCookie(cookie_name,access_info);
753 matches.push(cookie);
756 matches.toString=function toString(){return matches.join(":");}
757 matches.toValueString=function() {return matches.map(function(c){return c.toValueString();}).join(';');}
763 return new CookieJar()
767 //returns list of cookies that were set correctly
768 CookieJar.prototype.setCookies = function setCookies(cookies) {
769 cookies=Array.isArray(cookies)
771 :cookies.split(cookie_str_splitter);
773 for(var i=0;i<cookies.length;i++) {
774 var cookie = Cookie(cookies[i]);
775 if(this.setCookie(cookie)) {
776 successful.push(cookie);
784 require.define("/shred/request.js", function (require, module, exports, __dirname, __filename) {
785 // The request object encapsulates a request, creating a Node.js HTTP request and
786 // then handling the response.
788 var HTTP = require("http")
789 , HTTPS = require("https")
790 , parseUri = require("./parseUri")
791 , Emitter = require('events').EventEmitter
792 , sprintf = require("sprintf").sprintf
793 , Response = require("./response")
794 , HeaderMixins = require("./mixins/headers")
795 , Content = require("./content")
798 var STATUS_CODES = HTTP.STATUS_CODES || {
800 101 : 'Switching Protocols',
801 102 : 'Processing', // RFC 2518, obsoleted by RFC 4918
805 203 : 'Non-Authoritative Information',
807 205 : 'Reset Content',
808 206 : 'Partial Content',
809 207 : 'Multi-Status', // RFC 4918
810 300 : 'Multiple Choices',
811 301 : 'Moved Permanently',
812 302 : 'Moved Temporarily',
814 304 : 'Not Modified',
816 307 : 'Temporary Redirect',
818 401 : 'Unauthorized',
819 402 : 'Payment Required',
822 405 : 'Method Not Allowed',
823 406 : 'Not Acceptable',
824 407 : 'Proxy Authentication Required',
825 408 : 'Request Time-out',
828 411 : 'Length Required',
829 412 : 'Precondition Failed',
830 413 : 'Request Entity Too Large',
831 414 : 'Request-URI Too Large',
832 415 : 'Unsupported Media Type',
833 416 : 'Requested Range Not Satisfiable',
834 417 : 'Expectation Failed',
835 418 : 'I\'m a teapot', // RFC 2324
836 422 : 'Unprocessable Entity', // RFC 4918
837 423 : 'Locked', // RFC 4918
838 424 : 'Failed Dependency', // RFC 4918
839 425 : 'Unordered Collection', // RFC 4918
840 426 : 'Upgrade Required', // RFC 2817
841 500 : 'Internal Server Error',
842 501 : 'Not Implemented',
844 503 : 'Service Unavailable',
845 504 : 'Gateway Time-out',
846 505 : 'HTTP Version not supported',
847 506 : 'Variant Also Negotiates', // RFC 2295
848 507 : 'Insufficient Storage', // RFC 4918
849 509 : 'Bandwidth Limit Exceeded',
850 510 : 'Not Extended' // RFC 2774
853 // The Shred object itself constructs the `Request` object. You should rarely
854 // need to do this directly.
856 var Request = function(options) {
857 this.log = options.logger;
858 this.cookieJar = options.cookieJar;
859 this.encoding = options.encoding;
860 this.logCurl = options.logCurl;
861 processOptions(this,options||{});
865 // A `Request` has a number of properties, many of which help with details like
866 // URL parsing or defaulting the port for the request.
868 Object.defineProperties(Request.prototype, {
870 // - **url**. You can set the `url` property with a valid URL string and all the
871 // URL-related properties (host, port, etc.) will be automatically set on the
876 if (!this.scheme) { return null; }
877 return sprintf("%s://%s:%s%s",
878 this.scheme, this.host, this.port,
879 (this.proxy ? "/" : this.path) +
880 (this.query ? ("?" + this.query) : ""));
882 set: function(_url) {
883 _url = parseUri(_url);
884 this.scheme = _url.protocol;
885 this.host = _url.host;
886 this.port = _url.port;
887 this.path = _url.path;
888 this.query = _url.query;
894 // - **headers**. Returns a hash representing the request headers. You can't set
895 // this directly, only get it. You can add or modify headers by using the
896 // `setHeader` or `setHeaders` method. This ensures that the headers are
897 // normalized - that is, you don't accidentally send `Content-Type` and
898 // `content-type` headers. Keep in mind that if you modify the returned hash,
899 // it will *not* modify the request headers.
903 return this.getHeaders();
908 // - **port**. Unless you set the `port` explicitly or include it in the URL, it
909 // will default based on the scheme.
914 switch(this.scheme) {
915 case "https": return this._port = 443;
917 default: return this._port = 80;
922 set: function(value) { this._port = value; return this; },
926 // - **method**. The request method - `get`, `put`, `post`, etc. that will be
927 // used to make the request. Defaults to `get`.
931 return this._method = (this._method||"GET");
933 set: function(value) {
934 this._method = value; return this;
939 // - **query**. Can be set either with a query string or a hash (object). Get
940 // will always return a properly escaped query string or null if there is no
941 // query component for the request.
944 get: function() {return this._query;},
945 set: function(value) {
946 var stringify = function (hash) {
948 for (var key in hash) {
949 query += encodeURIComponent(key) + '=' + encodeURIComponent(hash[key]) + '&';
951 // Remove the last '&'
952 query = query.slice(0, -1);
957 if (typeof value === 'object') {
958 value = stringify(value);
969 // - **parameters**. This will return the query parameters in the form of a hash
973 get: function() { return QueryString.parse(this._query||""); },
977 // - **content**. (Aliased as `body`.) Set this to add a content entity to the
978 // request. Attempts to use the `content-type` header to determine what to do
979 // with the content value. Get this to get back a [`Content`
980 // object](./content.html).
983 get: function() { return this._body; },
984 set: function(value) {
985 this._body = new Content({
987 type: this.getHeader("Content-Type")
989 this.setHeader("Content-Type",this.content.type);
990 this.setHeader("Content-Length",this.content.length);
996 // - **timeout**. Used to determine how long to wait for a response. Does not
997 // distinguish between connect timeouts versus request timeouts. Set either in
998 // milliseconds or with an object with temporal attributes (hours, minutes,
999 // seconds) and convert it into milliseconds. Get will always return
1003 get: function() { return this._timeout; }, // in milliseconds
1004 set: function(timeout) {
1008 if (!timeout) return this;
1009 if (typeof timeout==="number") { milliseconds = timeout; }
1011 milliseconds = (timeout.milliseconds||0) +
1012 (1000 * ((timeout.seconds||0) +
1013 (60 * ((timeout.minutes||0) +
1014 (60 * (timeout.hours||0))))));
1016 this._timeout = milliseconds;
1023 // Alias `body` property to `content`. Since the [content object](./content.html)
1024 // has a `body` attribute, it's preferable to use `content` since you can then
1025 // access the raw content data using `content.body`.
1027 Object.defineProperty(Request.prototype,"content",
1028 Object.getOwnPropertyDescriptor(Request.prototype, "body"));
1030 // The `Request` object can be pretty overwhelming to view using the built-in
1031 // Node.js inspect method. We want to make it a bit more manageable. This
1032 // probably goes [too far in the other
1033 // direction](https://github.com/spire-io/shred/issues/2).
1035 Request.prototype.inspect = function () {
1037 var headers = this.format_headers();
1038 var summary = ["<Shred Request> ", request.method.toUpperCase(),
1039 request.url].join(" ")
1040 return [ summary, "- Headers:", headers].join("\n");
1043 Request.prototype.format_headers = function () {
1045 var headers = this._headers
1046 for (var key in headers) {
1047 if (headers.hasOwnProperty(key)) {
1048 var value = headers[key]
1049 array.push("\t" + key + ": " + value);
1052 return array.join("\n");
1055 // Allow chainable 'on's: shred.get({ ... }).on( ... ). You can pass in a
1056 // single function, a pair (event, function), or a hash:
1057 // { event: function, event: function }
1058 Request.prototype.on = function (eventOrHash, listener) {
1059 var emitter = this.emitter;
1060 // Pass in a single argument as a function then make it the default response handler
1061 if (arguments.length === 1 && typeof(eventOrHash) === 'function') {
1062 emitter.on('response', eventOrHash);
1063 } else if (arguments.length === 1 && typeof(eventOrHash) === 'object') {
1064 for (var key in eventOrHash) {
1065 if (eventOrHash.hasOwnProperty(key)) {
1066 emitter.on(key, eventOrHash[key]);
1070 emitter.on(eventOrHash, listener);
1075 // Add in the header methods. Again, these ensure we don't get the same header
1076 // multiple times with different case conventions.
1077 HeaderMixins.gettersAndSetters(Request);
1079 // `processOptions` is called from the constructor to handle all the work
1080 // associated with making sure we do our best to ensure we have a valid request.
1082 var processOptions = function(request,options) {
1084 request.log.debug("Processing request options ..");
1086 // We'll use `request.emitter` to manage the `on` event handlers.
1087 request.emitter = (new Emitter);
1089 request.agent = options.agent;
1091 // Set up the handlers ...
1093 for (var key in options.on) {
1094 if (options.on.hasOwnProperty(key)) {
1095 request.emitter.on(key, options.on[key]);
1100 // Make sure we were give a URL or a host
1101 if (!options.url && !options.host) {
1102 request.emitter.emit("request_error",
1103 new Error("No url or url options (host, port, etc.)"));
1107 // Allow for the [use of a proxy](http://www.jmarshall.com/easy/http/#proxies).
1110 if (options.proxy) {
1111 request.url = options.proxy;
1112 request.path = options.url;
1114 request.url = options.url;
1118 // Set the remaining options.
1119 request.query = options.query||options.parameters||request.query ;
1120 request.method = options.method;
1121 request.setHeader("user-agent",options.agent||"Shred");
1122 request.setHeaders(options.headers);
1124 if (request.cookieJar) {
1125 var cookies = request.cookieJar.getCookies( CookieAccessInfo( request.host, request.path ) );
1126 if (cookies.length) {
1127 var cookieString = request.getHeader('cookie')||'';
1128 for (var cookieIndex = 0; cookieIndex < cookies.length; ++cookieIndex) {
1129 if ( cookieString.length && cookieString[ cookieString.length - 1 ] != ';' )
1131 cookieString += ';';
1133 cookieString += cookies[ cookieIndex ].name + '=' + cookies[ cookieIndex ].value + ';';
1135 request.setHeader("cookie", cookieString);
1139 // The content entity can be set either using the `body` or `content` attributes.
1140 if (options.body||options.content) {
1141 request.content = options.body||options.content;
1143 request.timeout = options.timeout;
1147 // `createRequest` is also called by the constructor, after `processOptions`.
1148 // This actually makes the request and processes the response, so `createRequest`
1149 // is a bit of a misnomer.
1151 var createRequest = function(request) {
1154 request.log.debug("Creating request ..");
1155 request.log.debug(request);
1160 method: request.method,
1161 path: request.path + (request.query ? '?'+request.query : ""),
1162 headers: request.getHeaders(),
1163 // Node's HTTP/S modules will ignore this, but we are using the
1164 // browserify-http module in the browser for both HTTP and HTTPS, and this
1165 // is how you differentiate the two.
1166 scheme: request.scheme,
1167 // Use a provided agent. 'Undefined' is the default, which uses a global
1169 agent: request.agent
1172 if (request.logCurl) {
1176 var http = request.scheme == "http" ? HTTP : HTTPS;
1178 // Set up the real request using the selected library. The request won't be
1179 // sent until we call `.end()`.
1180 request._raw = http.request(reqParams, function(response) {
1181 request.log.debug("Received response ..");
1183 // We haven't timed out and we have a response, so make sure we clear the
1184 // timeout so it doesn't fire while we're processing the response.
1185 clearTimeout(timeout);
1187 // Construct a Shred `Response` object from the response. This will stream
1188 // the response, thus the need for the callback. We can access the response
1189 // entity safely once we're in the callback.
1190 response = new Response(response, request, function(response) {
1192 // Set up some event magic. The precedence is given first to
1193 // status-specific handlers, then to responses for a given event, and then
1194 // finally to the more general `response` handler. In the last case, we
1195 // need to first make sure we're not dealing with a a redirect.
1196 var emit = function(event) {
1197 var emitter = request.emitter;
1198 var textStatus = STATUS_CODES[response.status] ? STATUS_CODES[response.status].toLowerCase() : null;
1199 if (emitter.listeners(response.status).length > 0 || emitter.listeners(textStatus).length > 0) {
1200 emitter.emit(response.status, response);
1201 emitter.emit(textStatus, response);
1203 if (emitter.listeners(event).length>0) {
1204 emitter.emit(event, response);
1205 } else if (!response.isRedirect) {
1206 emitter.emit("response", response);
1207 //console.warn("Request has no event listener for status code " + response.status);
1212 // Next, check for a redirect. We simply repeat the request with the URL
1213 // given in the `Location` header. We fire a `redirect` event.
1214 if (response.isRedirect) {
1215 request.log.debug("Redirecting to "
1216 + response.getHeader("Location"));
1217 request.url = response.getHeader("Location");
1219 createRequest(request);
1221 // Okay, it's not a redirect. Is it an error of some kind?
1222 } else if (response.isError) {
1225 // It looks like we're good shape. Trigger the `success` event.
1231 // We're still setting up the request. Next, we're going to handle error cases
1232 // where we have no response. We don't emit an error event because that event
1233 // takes a response. We don't response handlers to have to check for a null
1234 // value. However, we [should introduce a different event
1235 // type](https://github.com/spire-io/shred/issues/3) for this type of error.
1236 request._raw.on("error", function(error) {
1237 request.emitter.emit("request_error", error);
1240 request._raw.on("socket", function(socket) {
1241 request.emitter.emit("socket", socket);
1244 // TCP timeouts should also trigger the "response_error" event.
1245 request._raw.on('socket', function () {
1246 request._raw.socket.on('timeout', function () {
1247 // This should trigger the "error" event on the raw request, which will
1248 // trigger the "response_error" on the shred request.
1249 request._raw.abort();
1254 // We're almost there. Next, we need to write the request entity to the
1255 // underlying request object.
1256 if (request.content) {
1257 request.log.debug("Streaming body: '" +
1258 request.content.data.slice(0,59) + "' ... ");
1259 request._raw.write(request.content.data);
1262 // Finally, we need to set up the timeout. We do this last so that we don't
1263 // start the clock ticking until the last possible moment.
1264 if (request.timeout) {
1265 timeout = setTimeout(function() {
1266 request.log.debug("Timeout fired, aborting request ...");
1267 request._raw.abort();
1268 request.emitter.emit("timeout", request);
1272 // The `.end()` method will cause the request to fire. Technically, it might
1273 // have already sent the headers and body.
1274 request.log.debug("Sending request ...");
1278 // Logs the curl command for the request.
1279 var logCurl = function (req) {
1280 var headers = req.getHeaders();
1281 var headerString = "";
1283 for (var key in headers) {
1284 headerString += '-H "' + key + ": " + headers[key] + '" ';
1290 bodyString += "-d '" + req.content.body + "' ";
1293 var query = req.query ? '?' + req.query : "";
1295 console.log("curl " +
1296 "-X " + req.method.toUpperCase() + " " +
1297 req.scheme + "://" + req.host + ":" + req.port + req.path + query + " " +
1304 module.exports = Request;
1308 require.define("http", function (require, module, exports, __dirname, __filename) {
1313 require.define("https", function (require, module, exports, __dirname, __filename) {
1318 require.define("/shred/parseUri.js", function (require, module, exports, __dirname, __filename) {
1320 // (c) Steven Levithan <stevenlevithan.com>
1323 function parseUri (str) {
1324 var o = parseUri.options,
1325 m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
1329 while (i--) uri[o.key[i]] = m[i] || "";
1332 uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
1333 if ($1) uri[o.q.name][$1] = $2;
1339 parseUri.options = {
1341 key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
1344 parser: /(?:^|&)([^&=]*)=?([^&]*)/g
1347 strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
1348 loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
1352 module.exports = parseUri;
1356 require.define("events", function (require, module, exports, __dirname, __filename) {
1357 if (!process.EventEmitter) process.EventEmitter = function () {};
1359 var EventEmitter = exports.EventEmitter = process.EventEmitter;
1360 var isArray = typeof Array.isArray === 'function'
1363 return Object.toString.call(xs) === '[object Array]'
1367 // By default EventEmitters will print a warning if more than
1368 // 10 listeners are added to it. This is a useful default which
1369 // helps finding memory leaks.
1371 // Obviously not all Emitters should be limited to 10. This function allows
1372 // that to be increased. Set to zero for unlimited.
1373 var defaultMaxListeners = 10;
1374 EventEmitter.prototype.setMaxListeners = function(n) {
1375 if (!this._events) this._events = {};
1376 this._events.maxListeners = n;
1380 EventEmitter.prototype.emit = function(type) {
1381 // If there is no 'error' event listener then throw.
1382 if (type === 'error') {
1383 if (!this._events || !this._events.error ||
1384 (isArray(this._events.error) && !this._events.error.length))
1386 if (arguments[1] instanceof Error) {
1387 throw arguments[1]; // Unhandled 'error' event
1389 throw new Error("Uncaught, unspecified 'error' event.");
1395 if (!this._events) return false;
1396 var handler = this._events[type];
1397 if (!handler) return false;
1399 if (typeof handler == 'function') {
1400 switch (arguments.length) {
1406 handler.call(this, arguments[1]);
1409 handler.call(this, arguments[1], arguments[2]);
1413 var args = Array.prototype.slice.call(arguments, 1);
1414 handler.apply(this, args);
1418 } else if (isArray(handler)) {
1419 var args = Array.prototype.slice.call(arguments, 1);
1421 var listeners = handler.slice();
1422 for (var i = 0, l = listeners.length; i < l; i++) {
1423 listeners[i].apply(this, args);
1432 // EventEmitter is defined in src/node_events.cc
1433 // EventEmitter.prototype.emit() is also defined there.
1434 EventEmitter.prototype.addListener = function(type, listener) {
1435 if ('function' !== typeof listener) {
1436 throw new Error('addListener only takes instances of Function');
1439 if (!this._events) this._events = {};
1441 // To avoid recursion in the case that type == "newListeners"! Before
1442 // adding it to the listeners, first emit "newListeners".
1443 this.emit('newListener', type, listener);
1445 if (!this._events[type]) {
1446 // Optimize the case of one listener. Don't need the extra array object.
1447 this._events[type] = listener;
1448 } else if (isArray(this._events[type])) {
1450 // Check for listener leak
1451 if (!this._events[type].warned) {
1453 if (this._events.maxListeners !== undefined) {
1454 m = this._events.maxListeners;
1456 m = defaultMaxListeners;
1459 if (m && m > 0 && this._events[type].length > m) {
1460 this._events[type].warned = true;
1461 console.error('(node) warning: possible EventEmitter memory ' +
1462 'leak detected. %d listeners added. ' +
1463 'Use emitter.setMaxListeners() to increase limit.',
1464 this._events[type].length);
1469 // If we've already got an array, just append.
1470 this._events[type].push(listener);
1472 // Adding the second element, need to change to array.
1473 this._events[type] = [this._events[type], listener];
1479 EventEmitter.prototype.on = EventEmitter.prototype.addListener;
1481 EventEmitter.prototype.once = function(type, listener) {
1483 self.on(type, function g() {
1484 self.removeListener(type, g);
1485 listener.apply(this, arguments);
1491 EventEmitter.prototype.removeListener = function(type, listener) {
1492 if ('function' !== typeof listener) {
1493 throw new Error('removeListener only takes instances of Function');
1496 // does not use listeners(), so no side effect of creating _events[type]
1497 if (!this._events || !this._events[type]) return this;
1499 var list = this._events[type];
1501 if (isArray(list)) {
1502 var i = list.indexOf(listener);
1503 if (i < 0) return this;
1505 if (list.length == 0)
1506 delete this._events[type];
1507 } else if (this._events[type] === listener) {
1508 delete this._events[type];
1514 EventEmitter.prototype.removeAllListeners = function(type) {
1515 // does not use listeners(), so no side effect of creating _events[type]
1516 if (type && this._events && this._events[type]) this._events[type] = null;
1520 EventEmitter.prototype.listeners = function(type) {
1521 if (!this._events) this._events = {};
1522 if (!this._events[type]) this._events[type] = [];
1523 if (!isArray(this._events[type])) {
1524 this._events[type] = [this._events[type]];
1526 return this._events[type];
1531 require.define("/node_modules/sprintf/package.json", function (require, module, exports, __dirname, __filename) {
1532 module.exports = {"main":"./lib/sprintf"}
1535 require.define("/node_modules/sprintf/lib/sprintf.js", function (require, module, exports, __dirname, __filename) {
1537 sprintf() for JavaScript 0.7-beta1
1538 http://www.diveintojavascript.com/projects/javascript-sprintf
1540 Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com>
1541 All rights reserved.
1543 Redistribution and use in source and binary forms, with or without
1544 modification, are permitted provided that the following conditions are met:
1545 * Redistributions of source code must retain the above copyright
1546 notice, this list of conditions and the following disclaimer.
1547 * Redistributions in binary form must reproduce the above copyright
1548 notice, this list of conditions and the following disclaimer in the
1549 documentation and/or other materials provided with the distribution.
1550 * Neither the name of sprintf() for JavaScript nor the
1551 names of its contributors may be used to endorse or promote products
1552 derived from this software without specific prior written permission.
1554 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1555 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1556 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
1557 DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY
1558 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
1559 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
1560 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
1561 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1562 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1563 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1567 2010.11.07 - 0.7-beta1-node
1568 - converted it to a node.js compatible module
1570 2010.09.06 - 0.7-beta1
1571 - features: vsprintf, support for named placeholders
1572 - enhancements: format cache, reduced global namespace pollution
1575 - reverted to 0.4 and fixed the bug regarding the sign of the number 0
1577 Thanks to Raphael Pigulla <raph (at] n3rd [dot) org> (http://www.n3rd.org/)
1578 who warned me about a bug in 0.5, I discovered that the last update was
1579 a regress. I appologize for that.
1582 - bug fix: 0 is now preceeded with a + sign
1583 - bug fix: the sign was not at the right position on padded results (Kamal Abdali)
1584 - switched from GPL to BSD license
1587 - unit test and patch (David Baird)
1590 - bug fix: no longer throws exception on empty paramenters (Hans Pufal)
1593 - feature: added argument swapping
1599 var sprintf = (function() {
1600 function get_type(variable) {
1601 return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase();
1603 function str_repeat(input, multiplier) {
1604 for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */}
1605 return output.join('');
1608 var str_format = function() {
1609 if (!str_format.cache.hasOwnProperty(arguments[0])) {
1610 str_format.cache[arguments[0]] = str_format.parse(arguments[0]);
1612 return str_format.format.call(null, str_format.cache[arguments[0]], arguments);
1615 str_format.format = function(parse_tree, argv) {
1616 var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length;
1617 for (i = 0; i < tree_length; i++) {
1618 node_type = get_type(parse_tree[i]);
1619 if (node_type === 'string') {
1620 output.push(parse_tree[i]);
1622 else if (node_type === 'array') {
1623 match = parse_tree[i]; // convenience purposes only
1624 if (match[2]) { // keyword argument
1626 for (k = 0; k < match[2].length; k++) {
1627 if (!arg.hasOwnProperty(match[2][k])) {
1628 throw(sprintf('[sprintf] property "%s" does not exist', match[2][k]));
1630 arg = arg[match[2][k]];
1633 else if (match[1]) { // positional argument (explicit)
1634 arg = argv[match[1]];
1636 else { // positional argument (implicit)
1637 arg = argv[cursor++];
1640 if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) {
1641 throw(sprintf('[sprintf] expecting number but found %s', get_type(arg)));
1644 case 'b': arg = arg.toString(2); break;
1645 case 'c': arg = String.fromCharCode(arg); break;
1646 case 'd': arg = parseInt(arg, 10); break;
1647 case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break;
1648 case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break;
1649 case 'o': arg = arg.toString(8); break;
1650 case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break;
1651 case 'u': arg = Math.abs(arg); break;
1652 case 'x': arg = arg.toString(16); break;
1653 case 'X': arg = arg.toString(16).toUpperCase(); break;
1655 arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg);
1656 pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' ';
1657 pad_length = match[6] - String(arg).length;
1658 pad = match[6] ? str_repeat(pad_character, pad_length) : '';
1659 output.push(match[5] ? arg + pad : pad + arg);
1662 return output.join('');
1665 str_format.cache = {};
1667 str_format.parse = function(fmt) {
1668 var _fmt = fmt, match = [], parse_tree = [], arg_names = 0;
1670 if ((match = /^[^\x25]+/.exec(_fmt)) !== null) {
1671 parse_tree.push(match[0]);
1673 else if ((match = /^\x25{2}/.exec(_fmt)) !== null) {
1674 parse_tree.push('%');
1676 else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) {
1679 var field_list = [], replacement_field = match[2], field_match = [];
1680 if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
1681 field_list.push(field_match[1]);
1682 while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
1683 if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) {
1684 field_list.push(field_match[1]);
1686 else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) {
1687 field_list.push(field_match[1]);
1690 throw('[sprintf] huh?');
1695 throw('[sprintf] huh?');
1697 match[2] = field_list;
1702 if (arg_names === 3) {
1703 throw('[sprintf] mixing positional and named placeholders is not (yet) supported');
1705 parse_tree.push(match);
1708 throw('[sprintf] huh?');
1710 _fmt = _fmt.substring(match[0].length);
1718 var vsprintf = function(fmt, argv) {
1720 return sprintf.apply(null, argv);
1723 exports.sprintf = sprintf;
1724 exports.vsprintf = vsprintf;
1727 require.define("/shred/response.js", function (require, module, exports, __dirname, __filename) {
1728 // The `Response object` encapsulates a Node.js HTTP response.
1730 var Content = require("./content")
1731 , HeaderMixins = require("./mixins/headers")
1732 , CookieJarLib = require( "cookiejar" )
1733 , Cookie = CookieJarLib.Cookie
1736 // Browser doesn't have zlib.
1739 zlib = require('zlib');
1741 // console.warn("no zlib library");
1744 // Iconv doesn't work in browser
1747 Iconv = require('iconv-lite');
1749 // console.warn("no iconv library");
1752 // Construct a `Response` object. You should never have to do this directly. The
1753 // `Request` object handles this, getting the raw response object and passing it
1754 // in here, along with the request. The callback allows us to stream the response
1755 // and then use the callback to let the request know when it's ready.
1756 var Response = function(raw, request, callback) {
1757 var response = this;
1760 // The `._setHeaders` method is "private"; you can't otherwise set headers on
1762 this._setHeaders.call(this,raw.headers);
1764 // store any cookies
1765 if (request.cookieJar && this.getHeader('set-cookie')) {
1766 var cookieStrings = this.getHeader('set-cookie');
1770 for (var i = 0; i < cookieStrings.length; i++) {
1771 var cookieString = cookieStrings[i];
1772 if (!cookieString) {
1776 if (!cookieString.match(/domain\=/i)) {
1777 cookieString += '; domain=' + request.host;
1780 if (!cookieString.match(/path\=/i)) {
1781 cookieString += '; path=' + request.path;
1785 cookie = new Cookie(cookieString);
1787 cookieObjs.push(cookie);
1790 console.warn("Tried to set bad cookie: " + cookieString);
1794 request.cookieJar.setCookies(cookieObjs);
1797 this.request = request;
1798 this.client = request.client;
1799 this.log = this.request.log;
1801 // Stream the response content entity and fire the callback when we're done.
1802 // Store the incoming data in a array of Buffers which we concatinate into one
1803 // buffer at the end. We need to use buffers instead of strings here in order
1804 // to preserve binary data.
1805 var chunkBuffers = [];
1807 raw.on("data", function(chunk) {
1808 chunkBuffers.push(chunk);
1809 dataLength += chunk.length;
1811 raw.on("end", function() {
1813 if (typeof Buffer === 'undefined') {
1814 // Just concatinate into a string
1815 body = chunkBuffers.join('');
1817 // Initialize new buffer and add the chunks one-at-a-time.
1818 body = new Buffer(dataLength);
1819 for (var i = 0, pos = 0; i < chunkBuffers.length; i++) {
1820 chunkBuffers[i].copy(body, pos);
1821 pos += chunkBuffers[i].length;
1825 var setBodyAndFinish = function (body) {
1826 response._body = new Content({
1828 type: response.getHeader("Content-Type")
1833 if (zlib && response.getHeader("Content-Encoding") === 'gzip'){
1834 zlib.gunzip(body, function (err, gunzippedBody) {
1835 if (Iconv && response.request.encoding){
1836 body = Iconv.fromEncoding(gunzippedBody,response.request.encoding);
1838 body = gunzippedBody.toString();
1840 setBodyAndFinish(body);
1844 if (response.request.encoding){
1845 body = Iconv.fromEncoding(body,response.request.encoding);
1847 setBodyAndFinish(body);
1852 // The `Response` object can be pretty overwhelming to view using the built-in
1853 // Node.js inspect method. We want to make it a bit more manageable. This
1854 // probably goes [too far in the other
1855 // direction](https://github.com/spire-io/shred/issues/2).
1857 Response.prototype = {
1858 inspect: function() {
1859 var response = this;
1860 var headers = this.format_headers();
1861 var summary = ["<Shred Response> ", response.status].join(" ")
1862 return [ summary, "- Headers:", headers].join("\n");
1864 format_headers: function () {
1866 var headers = this._headers
1867 for (var key in headers) {
1868 if (headers.hasOwnProperty(key)) {
1869 var value = headers[key]
1870 array.push("\t" + key + ": " + value);
1873 return array.join("\n");
1877 // `Response` object properties, all of which are read-only:
1878 Object.defineProperties(Response.prototype, {
1880 // - **status**. The HTTP status code for the response.
1882 get: function() { return this._raw.statusCode; },
1886 // - **content**. The HTTP content entity, if any. Provided as a [content
1887 // object](./content.html), which will attempt to convert the entity based upon
1888 // the `content-type` header. The converted value is available as
1889 // `content.data`. The original raw content entity is available as
1892 get: function() { return this._body; }
1895 get: function() { return this.body; },
1899 // - **isRedirect**. Is the response a redirect? These are responses with 3xx
1900 // status and a `Location` header.
1903 return (this.status>299
1905 &&this.getHeader("Location"));
1910 // - **isError**. Is the response an error? These are responses with status of
1914 return (this.status === 0 || this.status > 399)
1920 // Add in the [getters for accessing the normalized headers](./headers.js).
1921 HeaderMixins.getters(Response);
1922 HeaderMixins.privateSetters(Response);
1924 // Work around Mozilla bug #608735 [https://bugzil.la/608735], which causes
1925 // getAllResponseHeaders() to return {} if the response is a CORS request.
1926 // xhr.getHeader still works correctly.
1927 var getHeader = Response.prototype.getHeader;
1928 Response.prototype.getHeader = function (name) {
1929 return (getHeader.call(this,name) ||
1930 (typeof this._raw.getHeader === 'function' && this._raw.getHeader(name)));
1933 module.exports = Response;
1937 require.define("/shred/content.js", function (require, module, exports, __dirname, __filename) {
1939 // The purpose of the `Content` object is to abstract away the data conversions
1940 // to and from raw content entities as strings. For example, you want to be able
1941 // to pass in a Javascript object and have it be automatically converted into a
1942 // JSON string if the `content-type` is set to a JSON-based media type.
1943 // Conversely, you want to be able to transparently get back a Javascript object
1944 // in the response if the `content-type` is a JSON-based media-type.
1946 // One limitation of the current implementation is that it [assumes the `charset` is UTF-8](https://github.com/spire-io/shred/issues/5).
1948 // The `Content` constructor takes an options object, which *must* have either a
1949 // `body` or `data` property and *may* have a `type` property indicating the
1950 // media type. If there is no `type` attribute, a default will be inferred.
1951 var Content = function(options) {
1952 this.body = options.body;
1953 this.data = options.data;
1954 this.type = options.type;
1957 Content.prototype = {
1958 // Treat `toString()` as asking for the `content.body`. That is, the raw content entity.
1960 // toString: function() { return this.body; }
1962 // Commented out, but I've forgotten why. :/
1966 // `Content` objects have the following attributes:
1967 Object.defineProperties(Content.prototype,{
1969 // - **type**. Typically accessed as `content.type`, reflects the `content-type`
1970 // header associated with the request or response. If not passed as an options
1971 // to the constructor or set explicitly, it will infer the type the `data`
1972 // attribute, if possible, and, failing that, will default to `text/plain`.
1979 switch(typeof this._data) {
1980 case "string": return "text/plain";
1981 case "object": return "application/json";
1985 return "text/plain";
1987 set: function(value) {
1994 // - **data**. Typically accessed as `content.data`, reflects the content entity
1995 // converted into Javascript data. This can be a string, if the `type` is, say,
1996 // `text/plain`, but can also be a Javascript object. The conversion applied is
1997 // based on the `processor` attribute. The `data` attribute can also be set
1998 // directly, in which case the conversion will be done the other way, to infer
1999 // the `body` attribute.
2003 return this.processor.parser(this._body);
2008 set: function(data) {
2009 if (this._body&&data) Errors.setDataWithBody(this);
2016 // - **body**. Typically accessed as `content.body`, reflects the content entity
2017 // as a UTF-8 string. It is the mirror of the `data` attribute. If you set the
2018 // `data` attribute, the `body` attribute will be inferred and vice-versa. If
2019 // you attempt to set both, an exception is raised.
2023 return this.processor.stringify(this._data);
2025 return this.processor.stringify(this._body);
2028 set: function(body) {
2029 if (this._data&&body) Errors.setBodyWithData(this);
2036 // - **processor**. The functions that will be used to convert to/from `data` and
2037 // `body` attributes. You can add processors. The two that are built-in are for
2038 // `text/plain`, which is basically an identity transformation and
2039 // `application/json` and other JSON-based media types (including custom media
2040 // types with `+json`). You can add your own processors. See below.
2043 var processor = Content.processors[this.type];
2047 // Return the first processor that matches any part of the
2048 // content type. ex: application/vnd.foobar.baz+json will match json.
2049 var main = this.type.split(";")[0];
2050 var parts = main.split(/\+|\//);
2051 for (var i=0, l=parts.length; i < l; i++) {
2052 processor = Content.processors[parts[i]]
2054 return processor || {parser:identity,stringify:toString};
2060 // - **length**. Typically accessed as `content.length`, returns the length in
2061 // bytes of the raw content entity.
2064 if (typeof Buffer !== 'undefined') {
2065 return Buffer.byteLength(this.body);
2067 return this.body.length;
2072 Content.processors = {};
2074 // The `registerProcessor` function allows you to add your own processors to
2075 // convert content entities. Each processor consists of a Javascript object with
2077 // - **parser**. The function used to parse a raw content entity and convert it
2078 // into a Javascript data type.
2079 // - **stringify**. The function used to convert a Javascript data type into a
2080 // raw content entity.
2081 Content.registerProcessor = function(types,processor) {
2083 // You can pass an array of types that will trigger this processor, or just one.
2084 // We determine the array via duck-typing here.
2085 if (types.forEach) {
2086 types.forEach(function(type) {
2087 Content.processors[type] = processor;
2090 // If you didn't pass an array, we just use what you pass in.
2091 Content.processors[types] = processor;
2095 // Register the identity processor, which is used for text-based media types.
2096 var identity = function(x) { return x; }
2097 , toString = function(x) { return x.toString(); }
2098 Content.registerProcessor(
2099 ["text/html","text/plain","text"],
2100 { parser: identity, stringify: toString });
2102 // Register the JSON processor, which is used for JSON-based media types.
2103 Content.registerProcessor(
2104 ["application/json; charset=utf-8","application/json","json"],
2106 parser: function(string) {
2107 return JSON.parse(string);
2109 stringify: function(data) {
2110 return JSON.stringify(data); }});
2112 // Error functions are defined separately here in an attempt to make the code
2115 setDataWithBody: function(object) {
2116 throw new Error("Attempt to set data attribute of a content object " +
2117 "when the body attributes was already set.");
2119 setBodyWithData: function(object) {
2120 throw new Error("Attempt to set body attribute of a content object " +
2121 "when the data attributes was already set.");
2124 module.exports = Content;
2128 require.define("/shred/mixins/headers.js", function (require, module, exports, __dirname, __filename) {
2129 // The header mixins allow you to add HTTP header support to any object. This
2130 // might seem pointless: why not simply use a hash? The main reason is that, per
2131 // the [HTTP spec](http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2),
2132 // headers are case-insensitive. So, for example, `content-type` is the same as
2133 // `CONTENT-TYPE` which is the same as `Content-Type`. Since there is no way to
2134 // overload the index operator in Javascript, using a hash to represent the
2135 // headers means it's possible to have two conflicting values for a single
2138 // The solution to this is to provide explicit methods to set or get headers.
2139 // This also has the benefit of allowing us to introduce additional variations,
2140 // including snake case, which we automatically convert to what Matthew King has
2141 // dubbed "corset case" - the hyphen-separated names with initial caps:
2142 // `Content-Type`. We use corset-case just in case we're dealing with servers
2143 // that haven't properly implemented the spec.
2145 // Convert headers to corset-case. **Example:** `CONTENT-TYPE` will be converted
2146 // to `Content-Type`.
2148 var corsetCase = function(string) {
2149 return string;//.toLowerCase()
2151 // .replace(/(^|-)(\w)/g,
2152 // function(s) { return s.toUpperCase(); });
2155 // We suspect that `initializeHeaders` was once more complicated ...
2156 var initializeHeaders = function(object) {
2160 // Access the `_headers` property using lazy initialization. **Warning:** If you
2161 // mix this into an object that is using the `_headers` property already, you're
2162 // going to have trouble.
2163 var $H = function(object) {
2164 return object._headers||(object._headers=initializeHeaders(object));
2167 // Hide the implementations as private functions, separate from how we expose them.
2169 // The "real" `getHeader` function: get the header after normalizing the name.
2170 var getHeader = function(object,name) {
2171 return $H(object)[corsetCase(name)];
2174 // The "real" `getHeader` function: get one or more headers, or all of them
2175 // if you don't ask for any specifics.
2176 var getHeaders = function(object,names) {
2177 var keys = (names && names.length>0) ? names : Object.keys($H(object));
2178 var hash = keys.reduce(function(hash,key) {
2179 hash[key] = getHeader(object,key);
2182 // Freeze the resulting hash so you don't mistakenly think you're modifying
2183 // the real headers.
2184 Object.freeze(hash);
2188 // The "real" `setHeader` function: set a header, after normalizing the name.
2189 var setHeader = function(object,name,value) {
2190 $H(object)[corsetCase(name)] = value;
2194 // The "real" `setHeaders` function: set multiple headers based on a hash.
2195 var setHeaders = function(object,hash) {
2196 for( var key in hash ) { setHeader(object,key,hash[key]); };
2200 // Here's where we actually bind the functionality to an object. These mixins work by
2201 // exposing mixin functions. Each function mixes in a specific batch of features.
2205 getters: function(constructor) {
2206 constructor.prototype.getHeader = function(name) { return getHeader(this,name); };
2207 constructor.prototype.getHeaders = function() { return getHeaders(this,arguments); };
2209 // Add setters but as "private" methods.
2210 privateSetters: function(constructor) {
2211 constructor.prototype._setHeader = function(key,value) { return setHeader(this,key,value); };
2212 constructor.prototype._setHeaders = function(hash) { return setHeaders(this,hash); };
2215 setters: function(constructor) {
2216 constructor.prototype.setHeader = function(key,value) { return setHeader(this,key,value); };
2217 constructor.prototype.setHeaders = function(hash) { return setHeaders(this,hash); };
2219 // Add both getters and setters.
2220 gettersAndSetters: function(constructor) {
2221 constructor.prototype.getHeader = function(name) { return getHeader(this,name); };
2222 constructor.prototype.getHeaders = function() { return getHeaders(this,arguments); };
2223 constructor.prototype.setHeader = function(key,value) { return setHeader(this,key,value); };
2224 constructor.prototype.setHeaders = function(hash) { return setHeaders(this,hash); };
2230 require.define("/node_modules/iconv-lite/package.json", function (require, module, exports, __dirname, __filename) {
2234 require.define("/node_modules/iconv-lite/index.js", function (require, module, exports, __dirname, __filename) {
2236 var iconv = module.exports = {
2237 toEncoding: function(str, encoding) {
2238 return iconv.getCodec(encoding).toEncoding(str);
2240 fromEncoding: function(buf, encoding) {
2241 return iconv.getCodec(encoding).fromEncoding(buf);
2244 defaultCharUnicode: '�',
2245 defaultCharSingleByte: '?',
2247 // Get correct codec for given encoding.
2248 getCodec: function(encoding) {
2249 var enc = encoding || "utf8";
2250 var codecOptions = undefined;
2252 if (getType(enc) === "String")
2253 enc = enc.replace(/[- ]/g, "").toLowerCase();
2254 var codec = iconv.encodings[enc];
2255 var type = getType(codec);
2256 if (type === "String") {
2257 // Link to other encoding.
2258 codecOptions = {originalEncoding: enc};
2261 else if (type === "Object" && codec.type != undefined) {
2262 // Options for other encoding.
2263 codecOptions = codec;
2266 else if (type === "Function")
2268 return codec(codecOptions);
2270 throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')");
2274 // Define basic encodings
2276 internal: function(options) {
2278 toEncoding: function(str) {
2279 return new Buffer(ensureString(str), options.originalEncoding);
2281 fromEncoding: function(buf) {
2282 return ensureBuffer(buf).toString(options.originalEncoding);
2292 // Codepage single-byte encodings.
2293 singlebyte: function(options) {
2294 // Prepare chars if needed
2295 if (!options.chars || (options.chars.length !== 128 && options.chars.length !== 256))
2296 throw new Error("Encoding '"+options.type+"' has incorrect 'chars' (must be of len 128 or 256)");
2298 if (options.chars.length === 128)
2299 options.chars = asciiString + options.chars;
2301 if (!options.charsBuf) {
2302 options.charsBuf = new Buffer(options.chars, 'ucs2');
2305 if (!options.revCharsBuf) {
2306 options.revCharsBuf = new Buffer(65536);
2307 var defChar = iconv.defaultCharSingleByte.charCodeAt(0);
2308 for (var i = 0; i < options.revCharsBuf.length; i++)
2309 options.revCharsBuf[i] = defChar;
2310 for (var i = 0; i < options.chars.length; i++)
2311 options.revCharsBuf[options.chars.charCodeAt(i)] = i;
2315 toEncoding: function(str) {
2316 str = ensureString(str);
2318 var buf = new Buffer(str.length);
2319 var revCharsBuf = options.revCharsBuf;
2320 for (var i = 0; i < str.length; i++)
2321 buf[i] = revCharsBuf[str.charCodeAt(i)];
2325 fromEncoding: function(buf) {
2326 buf = ensureBuffer(buf);
2328 // Strings are immutable in JS -> we use ucs2 buffer to speed up computations.
2329 var charsBuf = options.charsBuf;
2330 var newBuf = new Buffer(buf.length*2);
2331 var idx1 = 0, idx2 = 0;
2332 for (var i = 0, _len = buf.length; i < _len; i++) {
2333 idx1 = buf[i]*2; idx2 = i*2;
2334 newBuf[idx2] = charsBuf[idx1];
2335 newBuf[idx2+1] = charsBuf[idx1+1];
2337 return newBuf.toString('ucs2');
2342 // Codepage double-byte encodings.
2343 table: function(options) {
2344 var table = options.table, key, revCharsTable = options.revCharsTable;
2346 throw new Error("Encoding '" + options.type +"' has incorect 'table' option");
2348 if(!revCharsTable) {
2349 revCharsTable = options.revCharsTable = {};
2350 for (key in table) {
2351 revCharsTable[table[key]] = parseInt(key);
2356 toEncoding: function(str) {
2357 str = ensureString(str);
2358 var strLen = str.length;
2359 var bufLen = strLen;
2360 for (var i = 0; i < strLen; i++)
2361 if (str.charCodeAt(i) >> 7)
2364 var newBuf = new Buffer(bufLen), gbkcode, unicode,
2365 defaultChar = revCharsTable[iconv.defaultCharUnicode.charCodeAt(0)];
2367 for (var i = 0, j = 0; i < strLen; i++) {
2368 unicode = str.charCodeAt(i);
2370 gbkcode = revCharsTable[unicode] || defaultChar;
2371 newBuf[j++] = gbkcode >> 8; //high byte;
2372 newBuf[j++] = gbkcode & 0xFF; //low byte
2374 newBuf[j++] = unicode;
2379 fromEncoding: function(buf) {
2380 buf = ensureBuffer(buf);
2381 var bufLen = buf.length, strLen = 0;
2382 for (var i = 0; i < bufLen; i++) {
2384 if (buf[i] & 0x80) //the high bit is 1, so this byte is gbkcode's high byte.skip next byte
2387 var newBuf = new Buffer(strLen*2), unicode, gbkcode,
2388 defaultChar = iconv.defaultCharUnicode.charCodeAt(0);
2390 for (var i = 0, j = 0; i < bufLen; i++, j+=2) {
2392 if (gbkcode & 0x80) {
2393 gbkcode = (gbkcode << 8) + buf[++i];
2394 unicode = table[gbkcode] || defaultChar;
2398 newBuf[j] = unicode & 0xFF; //low byte
2399 newBuf[j+1] = unicode >> 8; //high byte
2401 return newBuf.toString('ucs2');
2408 // Add aliases to convert functions
2409 iconv.encode = iconv.toEncoding;
2410 iconv.decode = iconv.fromEncoding;
2412 // Load other encodings from files in /encodings dir.
2413 var encodingsDir = __dirname+"/encodings/",
2415 fs.readdirSync(encodingsDir).forEach(function(file) {
2416 if(fs.statSync(encodingsDir + file).isDirectory()) return;
2417 var encodings = require(encodingsDir + file)
2418 for (var key in encodings)
2419 iconv.encodings[key] = encodings[key]
2423 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'+
2424 ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f';
2426 var ensureBuffer = function(buf) {
2427 buf = buf || new Buffer(0);
2428 return (buf instanceof Buffer) ? buf : new Buffer(buf.toString(), "utf8");
2431 var ensureString = function(str) {
2433 return (str instanceof String) ? str : str.toString((str instanceof Buffer) ? 'utf8' : undefined);
2436 var getType = function(obj) {
2437 return Object.prototype.toString.call(obj).slice(8, -1);
2443 require.define("/node_modules/http-browserify/package.json", function (require, module, exports, __dirname, __filename) {
2444 module.exports = {"main":"index.js","browserify":"browser.js"}
2447 require.define("/node_modules/http-browserify/browser.js", function (require, module, exports, __dirname, __filename) {
2448 var http = module.exports;
2449 var EventEmitter = require('events').EventEmitter;
2450 var Request = require('./lib/request');
2452 http.request = function (params, cb) {
2453 if (!params) params = {};
2454 if (!params.host) params.host = window.location.host.split(':')[0];
2455 if (!params.port) params.port = window.location.port;
2457 var req = new Request(new xhrHttp, params);
2458 if (cb) req.on('response', cb);
2462 http.get = function (params, cb) {
2463 params.method = 'GET';
2464 var req = http.request(params, cb);
2469 var xhrHttp = (function () {
2470 if (typeof window === 'undefined') {
2471 throw new Error('no window object present');
2473 else if (window.XMLHttpRequest) {
2474 return window.XMLHttpRequest;
2476 else if (window.ActiveXObject) {
2478 'Msxml2.XMLHTTP.6.0',
2479 'Msxml2.XMLHTTP.3.0',
2482 for (var i = 0; i < axs.length; i++) {
2484 var ax = new(window.ActiveXObject)(axs[i]);
2485 return function () {
2492 return new(window.ActiveXObject)(axs[i]);
2498 throw new Error('ajax not supported in this browser')
2501 throw new Error('ajax not supported in this browser');
2505 http.STATUS_CODES = {
2507 101 : 'Switching Protocols',
2508 102 : 'Processing', // RFC 2518, obsoleted by RFC 4918
2512 203 : 'Non-Authoritative Information',
2514 205 : 'Reset Content',
2515 206 : 'Partial Content',
2516 207 : 'Multi-Status', // RFC 4918
2517 300 : 'Multiple Choices',
2518 301 : 'Moved Permanently',
2519 302 : 'Moved Temporarily',
2521 304 : 'Not Modified',
2523 307 : 'Temporary Redirect',
2524 400 : 'Bad Request',
2525 401 : 'Unauthorized',
2526 402 : 'Payment Required',
2529 405 : 'Method Not Allowed',
2530 406 : 'Not Acceptable',
2531 407 : 'Proxy Authentication Required',
2532 408 : 'Request Time-out',
2535 411 : 'Length Required',
2536 412 : 'Precondition Failed',
2537 413 : 'Request Entity Too Large',
2538 414 : 'Request-URI Too Large',
2539 415 : 'Unsupported Media Type',
2540 416 : 'Requested Range Not Satisfiable',
2541 417 : 'Expectation Failed',
2542 418 : 'I\'m a teapot', // RFC 2324
2543 422 : 'Unprocessable Entity', // RFC 4918
2544 423 : 'Locked', // RFC 4918
2545 424 : 'Failed Dependency', // RFC 4918
2546 425 : 'Unordered Collection', // RFC 4918
2547 426 : 'Upgrade Required', // RFC 2817
2548 500 : 'Internal Server Error',
2549 501 : 'Not Implemented',
2550 502 : 'Bad Gateway',
2551 503 : 'Service Unavailable',
2552 504 : 'Gateway Time-out',
2553 505 : 'HTTP Version not supported',
2554 506 : 'Variant Also Negotiates', // RFC 2295
2555 507 : 'Insufficient Storage', // RFC 4918
2556 509 : 'Bandwidth Limit Exceeded',
2557 510 : 'Not Extended' // RFC 2774
2562 require.define("/node_modules/http-browserify/lib/request.js", function (require, module, exports, __dirname, __filename) {
2563 var EventEmitter = require('events').EventEmitter;
2564 var Response = require('./response');
2565 var isSafeHeader = require('./isSafeHeader');
2567 var Request = module.exports = function (xhr, params) {
2572 var uri = params.host + ':' + params.port + (params.path || '/');
2575 params.method || 'GET',
2576 (params.scheme || 'http') + '://' + uri,
2580 if (params.headers) {
2581 Object.keys(params.headers).forEach(function (key) {
2582 if (!isSafeHeader(key)) return;
2583 var value = params.headers[key];
2584 if (Array.isArray(value)) {
2585 value.forEach(function (v) {
2586 xhr.setRequestHeader(key, v);
2589 else xhr.setRequestHeader(key, value)
2593 var res = new Response(xhr);
2594 res.on('ready', function () {
2595 self.emit('response', res);
2598 xhr.onreadystatechange = function () {
2603 Request.prototype = new EventEmitter;
2605 Request.prototype.setHeader = function (key, value) {
2606 if ((Array.isArray && Array.isArray(value))
2607 || value instanceof Array) {
2608 for (var i = 0; i < value.length; i++) {
2609 this.xhr.setRequestHeader(key, value[i]);
2613 this.xhr.setRequestHeader(key, value);
2617 Request.prototype.write = function (s) {
2621 Request.prototype.end = function (s) {
2622 if (s !== undefined) this.write(s);
2623 this.xhr.send(this.body);
2628 require.define("/node_modules/http-browserify/lib/response.js", function (require, module, exports, __dirname, __filename) {
2629 var EventEmitter = require('events').EventEmitter;
2630 var isSafeHeader = require('./isSafeHeader');
2632 var Response = module.exports = function (xhr) {
2637 Response.prototype = new EventEmitter;
2644 function parseHeaders (xhr) {
2645 var lines = xhr.getAllResponseHeaders().split(/\r?\n/);
2647 for (var i = 0; i < lines.length; i++) {
2648 var line = lines[i];
2649 if (line === '') continue;
2651 var m = line.match(/^([^:]+):\s*(.*)/);
2653 var key = m[1].toLowerCase(), value = m[2];
2655 if (headers[key] !== undefined) {
2656 if ((Array.isArray && Array.isArray(headers[key]))
2657 || headers[key] instanceof Array) {
2658 headers[key].push(value);
2661 headers[key] = [ headers[key], value ];
2665 headers[key] = value;
2669 headers[line] = true;
2675 Response.prototype.getHeader = function (key) {
2676 var header = this.headers ? this.headers[key.toLowerCase()] : null;
2677 if (header) return header;
2679 // Work around Mozilla bug #608735 [https://bugzil.la/608735], which causes
2680 // getAllResponseHeaders() to return {} if the response is a CORS request.
2681 // xhr.getHeader still works correctly.
2682 if (isSafeHeader(key)) {
2683 return this.xhr.getResponseHeader(key);
2688 Response.prototype.handle = function () {
2690 if (xhr.readyState === 2 && capable.status2) {
2692 this.statusCode = xhr.status;
2693 this.headers = parseHeaders(xhr);
2696 capable.status2 = false;
2699 if (capable.status2) {
2703 else if (capable.streaming && xhr.readyState === 3) {
2705 if (!this.statusCode) {
2706 this.statusCode = xhr.status;
2707 this.headers = parseHeaders(xhr);
2717 capable.streaming = false;
2720 else if (xhr.readyState === 4) {
2721 if (!this.statusCode) {
2722 this.statusCode = xhr.status;
2728 this.emit('error', xhr.responseText);
2730 else this.emit('end');
2734 Response.prototype.write = function () {
2736 if (xhr.responseText.length > this.offset) {
2737 this.emit('data', xhr.responseText.slice(this.offset));
2738 this.offset = xhr.responseText.length;
2744 require.define("/node_modules/http-browserify/lib/isSafeHeader.js", function (require, module, exports, __dirname, __filename) {
2745 // Taken from http://dxr.mozilla.org/mozilla/mozilla-central/content/base/src/nsXMLHttpRequest.cpp.html
2746 var unsafeHeaders = [
2749 "access-control-request-headers",
2750 "access-control-request-method",
2755 "content-transfer-encoding",
2765 "transfer-encoding",
2771 module.exports = function (headerName) {
2772 if (!headerName) return false;
2773 return (unsafeHeaders.indexOf(headerName.toLowerCase()) === -1)
2778 require.alias("http-browserify", "/node_modules/http");
2780 require.alias("http-browserify", "/node_modules/https");