github.com/enmand/kubernetes@v1.2.0-alpha.0/third_party/swagger-ui/lib/shred.bundle.js (about) 1 var require = function (file, cwd) { 2 var resolved = require.resolve(file, cwd || '/'); 3 var mod = require.modules[resolved]; 4 if (!mod) throw new Error( 5 'Failed to resolve module ' + file + ', tried ' + resolved 6 ); 7 var res = mod._cached ? mod._cached : mod(); 8 return res; 9 } 10 11 require.paths = []; 12 require.modules = {}; 13 require.extensions = [".js",".coffee"]; 14 15 require._core = { 16 'assert': true, 17 'events': true, 18 'fs': true, 19 'path': true, 20 'vm': true 21 }; 22 23 require.resolve = (function () { 24 return function (x, cwd) { 25 if (!cwd) cwd = '/'; 26 27 if (require._core[x]) return x; 28 var path = require.modules.path(); 29 var y = cwd || '.'; 30 31 if (x.match(/^(?:\.\.?\/|\/)/)) { 32 var m = loadAsFileSync(path.resolve(y, x)) 33 || loadAsDirectorySync(path.resolve(y, x)); 34 if (m) return m; 35 } 36 37 var n = loadNodeModulesSync(x, y); 38 if (n) return n; 39 40 throw new Error("Cannot find module '" + x + "'"); 41 42 function loadAsFileSync (x) { 43 if (require.modules[x]) { 44 return x; 45 } 46 47 for (var i = 0; i < require.extensions.length; i++) { 48 var ext = require.extensions[i]; 49 if (require.modules[x + ext]) return x + ext; 50 } 51 } 52 53 function loadAsDirectorySync (x) { 54 x = x.replace(/\/+$/, ''); 55 var pkgfile = x + '/package.json'; 56 if (require.modules[pkgfile]) { 57 var pkg = require.modules[pkgfile](); 58 var b = pkg.browserify; 59 if (typeof b === 'object' && b.main) { 60 var m = loadAsFileSync(path.resolve(x, b.main)); 61 if (m) return m; 62 } 63 else if (typeof b === 'string') { 64 var m = loadAsFileSync(path.resolve(x, b)); 65 if (m) return m; 66 } 67 else if (pkg.main) { 68 var m = loadAsFileSync(path.resolve(x, pkg.main)); 69 if (m) return m; 70 } 71 } 72 73 return loadAsFileSync(x + '/index'); 74 } 75 76 function loadNodeModulesSync (x, start) { 77 var dirs = nodeModulesPathsSync(start); 78 for (var i = 0; i < dirs.length; i++) { 79 var dir = dirs[i]; 80 var m = loadAsFileSync(dir + '/' + x); 81 if (m) return m; 82 var n = loadAsDirectorySync(dir + '/' + x); 83 if (n) return n; 84 } 85 86 var m = loadAsFileSync(x); 87 if (m) return m; 88 } 89 90 function nodeModulesPathsSync (start) { 91 var parts; 92 if (start === '/') parts = [ '' ]; 93 else parts = path.normalize(start).split('/'); 94 95 var dirs = []; 96 for (var i = parts.length - 1; i >= 0; i--) { 97 if (parts[i] === 'node_modules') continue; 98 var dir = parts.slice(0, i + 1).join('/') + '/node_modules'; 99 dirs.push(dir); 100 } 101 102 return dirs; 103 } 104 }; 105 })(); 106 107 require.alias = function (from, to) { 108 var path = require.modules.path(); 109 var res = null; 110 try { 111 res = require.resolve(from + '/package.json', '/'); 112 } 113 catch (err) { 114 res = require.resolve(from, '/'); 115 } 116 var basedir = path.dirname(res); 117 118 var keys = (Object.keys || function (obj) { 119 var res = []; 120 for (var key in obj) res.push(key) 121 return res; 122 })(require.modules); 123 124 for (var i = 0; i < keys.length; i++) { 125 var key = keys[i]; 126 if (key.slice(0, basedir.length + 1) === basedir + '/') { 127 var f = key.slice(basedir.length); 128 require.modules[to + f] = require.modules[basedir + f]; 129 } 130 else if (key === basedir) { 131 require.modules[to] = require.modules[basedir]; 132 } 133 } 134 }; 135 136 require.define = function (filename, fn) { 137 var dirname = require._core[filename] 138 ? '' 139 : require.modules.path().dirname(filename) 140 ; 141 142 var require_ = function (file) { 143 return require(file, dirname) 144 }; 145 require_.resolve = function (name) { 146 return require.resolve(name, dirname); 147 }; 148 require_.modules = require.modules; 149 require_.define = require.define; 150 var module_ = { exports : {} }; 151 152 require.modules[filename] = function () { 153 require.modules[filename]._cached = module_.exports; 154 fn.call( 155 module_.exports, 156 require_, 157 module_, 158 module_.exports, 159 dirname, 160 filename 161 ); 162 require.modules[filename]._cached = module_.exports; 163 return module_.exports; 164 }; 165 }; 166 167 if (typeof process === 'undefined') process = {}; 168 169 if (!process.nextTick) process.nextTick = (function () { 170 var queue = []; 171 var canPost = typeof window !== 'undefined' 172 && window.postMessage && window.addEventListener 173 ; 174 175 if (canPost) { 176 window.addEventListener('message', function (ev) { 177 if (ev.source === window && ev.data === 'browserify-tick') { 178 ev.stopPropagation(); 179 if (queue.length > 0) { 180 var fn = queue.shift(); 181 fn(); 182 } 183 } 184 }, true); 185 } 186 187 return function (fn) { 188 if (canPost) { 189 queue.push(fn); 190 window.postMessage('browserify-tick', '*'); 191 } 192 else setTimeout(fn, 0); 193 }; 194 })(); 195 196 if (!process.title) process.title = 'browser'; 197 198 if (!process.binding) process.binding = function (name) { 199 if (name === 'evals') return require('vm') 200 else throw new Error('No such module') 201 }; 202 203 if (!process.cwd) process.cwd = function () { return '.' }; 204 205 require.define("path", function (require, module, exports, __dirname, __filename) { 206 function filter (xs, fn) { 207 var res = []; 208 for (var i = 0; i < xs.length; i++) { 209 if (fn(xs[i], i, xs)) res.push(xs[i]); 210 } 211 return res; 212 } 213 214 // resolves . and .. elements in a path array with directory names there 215 // must be no slashes, empty elements, or device names (c:\) in the array 216 // (so also no leading and trailing slashes - it does not distinguish 217 // relative and absolute paths) 218 function normalizeArray(parts, allowAboveRoot) { 219 // if the path tries to go above the root, `up` ends up > 0 220 var up = 0; 221 for (var i = parts.length; i >= 0; i--) { 222 var last = parts[i]; 223 if (last == '.') { 224 parts.splice(i, 1); 225 } else if (last === '..') { 226 parts.splice(i, 1); 227 up++; 228 } else if (up) { 229 parts.splice(i, 1); 230 up--; 231 } 232 } 233 234 // if the path is allowed to go above the root, restore leading ..s 235 if (allowAboveRoot) { 236 for (; up--; up) { 237 parts.unshift('..'); 238 } 239 } 240 241 return parts; 242 } 243 244 // Regex to split a filename into [*, dir, basename, ext] 245 // posix version 246 var splitPathRe = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/; 247 248 // path.resolve([from ...], to) 249 // posix version 250 exports.resolve = function() { 251 var resolvedPath = '', 252 resolvedAbsolute = false; 253 254 for (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) { 255 var path = (i >= 0) 256 ? arguments[i] 257 : process.cwd(); 258 259 // Skip empty and invalid entries 260 if (typeof path !== 'string' || !path) { 261 continue; 262 } 263 264 resolvedPath = path + '/' + resolvedPath; 265 resolvedAbsolute = path.charAt(0) === '/'; 266 } 267 268 // At this point the path should be resolved to a full absolute path, but 269 // handle relative paths to be safe (might happen when process.cwd() fails) 270 271 // Normalize the path 272 resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { 273 return !!p; 274 }), !resolvedAbsolute).join('/'); 275 276 return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; 277 }; 278 279 // path.normalize(path) 280 // posix version 281 exports.normalize = function(path) { 282 var isAbsolute = path.charAt(0) === '/', 283 trailingSlash = path.slice(-1) === '/'; 284 285 // Normalize the path 286 path = normalizeArray(filter(path.split('/'), function(p) { 287 return !!p; 288 }), !isAbsolute).join('/'); 289 290 if (!path && !isAbsolute) { 291 path = '.'; 292 } 293 if (path && trailingSlash) { 294 path += '/'; 295 } 296 297 return (isAbsolute ? '/' : '') + path; 298 }; 299 300 301 // posix version 302 exports.join = function() { 303 var paths = Array.prototype.slice.call(arguments, 0); 304 return exports.normalize(filter(paths, function(p, index) { 305 return p && typeof p === 'string'; 306 }).join('/')); 307 }; 308 309 310 exports.dirname = function(path) { 311 var dir = splitPathRe.exec(path)[1] || ''; 312 var isWindows = false; 313 if (!dir) { 314 // No dirname 315 return '.'; 316 } else if (dir.length === 1 || 317 (isWindows && dir.length <= 3 && dir.charAt(1) === ':')) { 318 // It is just a slash or a drive letter with a slash 319 return dir; 320 } else { 321 // It is a full dirname, strip trailing slash 322 return dir.substring(0, dir.length - 1); 323 } 324 }; 325 326 327 exports.basename = function(path, ext) { 328 var f = splitPathRe.exec(path)[2] || ''; 329 // TODO: make this comparison case-insensitive on windows? 330 if (ext && f.substr(-1 * ext.length) === ext) { 331 f = f.substr(0, f.length - ext.length); 332 } 333 return f; 334 }; 335 336 337 exports.extname = function(path) { 338 return splitPathRe.exec(path)[3] || ''; 339 }; 340 341 }); 342 343 require.define("/shred.js", function (require, module, exports, __dirname, __filename) { 344 // Shred is an HTTP client library intended to simplify the use of Node's 345 // built-in HTTP library. In particular, we wanted to make it easier to interact 346 // with HTTP-based APIs. 347 // 348 // See the [examples](./examples.html) for more details. 349 350 // Ax is a nice logging library we wrote. You can use any logger, providing it 351 // has `info`, `warn`, `debug`, and `error` methods that take a string. 352 var Ax = require("ax") 353 , CookieJarLib = require( "cookiejar" ) 354 , CookieJar = CookieJarLib.CookieJar 355 ; 356 357 // Shred takes some options, including a logger and request defaults. 358 359 var Shred = function(options) { 360 options = (options||{}); 361 this.agent = options.agent; 362 this.defaults = options.defaults||{}; 363 this.log = options.logger||(new Ax({ level: "info" })); 364 this._sharedCookieJar = new CookieJar(); 365 this.logCurl = options.logCurl || false; 366 }; 367 368 // Most of the real work is done in the request and reponse classes. 369 370 Shred.Request = require("./shred/request"); 371 Shred.Response = require("./shred/response"); 372 373 // The `request` method kicks off a new request, instantiating a new `Request` 374 // object and passing along whatever default options we were given. 375 376 Shred.prototype = { 377 request: function(options) { 378 options.logger = this.log; 379 options.logCurl = options.logCurl || this.logCurl; 380 options.cookieJar = ( 'cookieJar' in options ) ? options.cookieJar : this._sharedCookieJar; // let them set cookieJar = null 381 options.agent = options.agent || this.agent; 382 // fill in default options 383 for (var key in this.defaults) { 384 if (this.defaults.hasOwnProperty(key) && !options[key]) { 385 options[key] = this.defaults[key] 386 } 387 } 388 return new Shred.Request(options); 389 } 390 }; 391 392 // Define a bunch of convenience methods so that you don't have to include 393 // a `method` property in your request options. 394 395 "get put post delete".split(" ").forEach(function(method) { 396 Shred.prototype[method] = function(options) { 397 options.method = method; 398 return this.request(options); 399 }; 400 }); 401 402 403 module.exports = Shred; 404 405 }); 406 407 require.define("/node_modules/ax/package.json", function (require, module, exports, __dirname, __filename) { 408 module.exports = {"main":"./lib/ax.js"} 409 }); 410 411 require.define("/node_modules/ax/lib/ax.js", function (require, module, exports, __dirname, __filename) { 412 var inspect = require("util").inspect 413 , fs = require("fs") 414 ; 415 416 417 // this is a quick-and-dirty logger. there are other nicer loggers out there 418 // but the ones i found were also somewhat involved. this one has a Ruby 419 // logger type interface 420 // 421 // we can easily replace this, provide the info, debug, etc. methods are the 422 // same. or, we can change Haiku to use a more standard node.js interface 423 424 var format = function(level,message) { 425 var debug = (level=="debug"||level=="error"); 426 if (!message) { return message.toString(); } 427 if (typeof(message) == "object") { 428 if (message instanceof Error && debug) { 429 return message.stack; 430 } else { 431 return inspect(message); 432 } 433 } else { 434 return message.toString(); 435 } 436 }; 437 438 var noOp = function(message) { return this; } 439 var makeLogger = function(level,fn) { 440 return function(message) { 441 this.stream.write(this.format(level, message)+"\n"); 442 return this; 443 } 444 }; 445 446 var Logger = function(options) { 447 var logger = this; 448 var options = options||{}; 449 450 // Default options 451 options.level = options.level || "info"; 452 options.timestamp = options.timestamp || true; 453 options.prefix = options.prefix || ""; 454 logger.options = options; 455 456 // Allows a prefix to be added to the message. 457 // 458 // var logger = new Ax({ module: 'Haiku' }) 459 // logger.warn('this is going to be awesome!'); 460 // //=> Haiku: this is going to be awesome! 461 // 462 if (logger.options.module){ 463 logger.options.prefix = logger.options.module; 464 } 465 466 // Write to stderr or a file 467 if (logger.options.file){ 468 logger.stream = fs.createWriteStream(logger.options.file, {"flags": "a"}); 469 } else { 470 if(process.title === "node") 471 logger.stream = process.stderr; 472 else if(process.title === "browser") 473 logger.stream = function () { 474 // Work around weird console context issue: http://code.google.com/p/chromium/issues/detail?id=48662 475 return console[logger.options.level].apply(console, arguments); 476 }; 477 } 478 479 switch(logger.options.level){ 480 case 'debug': 481 ['debug', 'info', 'warn'].forEach(function (level) { 482 logger[level] = Logger.writer(level); 483 }); 484 case 'info': 485 ['info', 'warn'].forEach(function (level) { 486 logger[level] = Logger.writer(level); 487 }); 488 case 'warn': 489 logger.warn = Logger.writer('warn'); 490 } 491 } 492 493 // Used to define logger methods 494 Logger.writer = function(level){ 495 return function(message){ 496 var logger = this; 497 498 if(process.title === "node") 499 logger.stream.write(logger.format(level, message) + '\n'); 500 else if(process.title === "browser") 501 logger.stream(logger.format(level, message) + '\n'); 502 503 }; 504 } 505 506 507 Logger.prototype = { 508 info: function(){}, 509 debug: function(){}, 510 warn: function(){}, 511 error: Logger.writer('error'), 512 format: function(level, message){ 513 if (! message) return ''; 514 515 var logger = this 516 , prefix = logger.options.prefix 517 , timestamp = logger.options.timestamp ? " " + (new Date().toISOString()) : "" 518 ; 519 520 return (prefix + timestamp + ": " + message); 521 } 522 }; 523 524 module.exports = Logger; 525 526 }); 527 528 require.define("util", function (require, module, exports, __dirname, __filename) { 529 // todo 530 531 }); 532 533 require.define("fs", function (require, module, exports, __dirname, __filename) { 534 // nothing to see here... no file methods for the browser 535 536 }); 537 538 require.define("/node_modules/cookiejar/package.json", function (require, module, exports, __dirname, __filename) { 539 module.exports = {"main":"cookiejar.js"} 540 }); 541 542 require.define("/node_modules/cookiejar/cookiejar.js", function (require, module, exports, __dirname, __filename) { 543 exports.CookieAccessInfo=CookieAccessInfo=function CookieAccessInfo(domain,path,secure,script) { 544 if(this instanceof CookieAccessInfo) { 545 this.domain=domain||undefined; 546 this.path=path||"/"; 547 this.secure=!!secure; 548 this.script=!!script; 549 return this; 550 } 551 else { 552 return new CookieAccessInfo(domain,path,secure,script) 553 } 554 } 555 556 exports.Cookie=Cookie=function Cookie(cookiestr) { 557 if(cookiestr instanceof Cookie) { 558 return cookiestr; 559 } 560 else { 561 if(this instanceof Cookie) { 562 this.name = null; 563 this.value = null; 564 this.expiration_date = Infinity; 565 this.path = "/"; 566 this.domain = null; 567 this.secure = false; //how to define? 568 this.noscript = false; //httponly 569 if(cookiestr) { 570 this.parse(cookiestr) 571 } 572 return this; 573 } 574 return new Cookie(cookiestr) 575 } 576 } 577 578 Cookie.prototype.toString = function toString() { 579 var str=[this.name+"="+this.value]; 580 if(this.expiration_date !== Infinity) { 581 str.push("expires="+(new Date(this.expiration_date)).toGMTString()); 582 } 583 if(this.domain) { 584 str.push("domain="+this.domain); 585 } 586 if(this.path) { 587 str.push("path="+this.path); 588 } 589 if(this.secure) { 590 str.push("secure"); 591 } 592 if(this.noscript) { 593 str.push("httponly"); 594 } 595 return str.join("; "); 596 } 597 598 Cookie.prototype.toValueString = function toValueString() { 599 return this.name+"="+this.value; 600 } 601 602 var cookie_str_splitter=/[:](?=\s*[a-zA-Z0-9_\-]+\s*[=])/g 603 Cookie.prototype.parse = function parse(str) { 604 if(this instanceof Cookie) { 605 var parts=str.split(";") 606 , pair=parts[0].match(/([^=]+)=((?:.|\n)*)/) 607 , key=pair[1] 608 , value=pair[2]; 609 this.name = key; 610 this.value = value; 611 612 for(var i=1;i<parts.length;i++) { 613 pair=parts[i].match(/([^=]+)(?:=((?:.|\n)*))?/) 614 , key=pair[1].trim().toLowerCase() 615 , value=pair[2]; 616 switch(key) { 617 case "httponly": 618 this.noscript = true; 619 break; 620 case "expires": 621 this.expiration_date = value 622 ? Number(Date.parse(value)) 623 : Infinity; 624 break; 625 case "path": 626 this.path = value 627 ? value.trim() 628 : ""; 629 break; 630 case "domain": 631 this.domain = value 632 ? value.trim() 633 : ""; 634 break; 635 case "secure": 636 this.secure = true; 637 break 638 } 639 } 640 641 return this; 642 } 643 return new Cookie().parse(str) 644 } 645 646 Cookie.prototype.matches = function matches(access_info) { 647 if(this.noscript && access_info.script 648 || this.secure && !access_info.secure 649 || !this.collidesWith(access_info)) { 650 return false 651 } 652 return true; 653 } 654 655 Cookie.prototype.collidesWith = function collidesWith(access_info) { 656 if((this.path && !access_info.path) || (this.domain && !access_info.domain)) { 657 return false 658 } 659 if(this.path && access_info.path.indexOf(this.path) !== 0) { 660 return false; 661 } 662 if (this.domain===access_info.domain) { 663 return true; 664 } 665 else if(this.domain && this.domain.charAt(0)===".") 666 { 667 var wildcard=access_info.domain.indexOf(this.domain.slice(1)) 668 if(wildcard===-1 || wildcard!==access_info.domain.length-this.domain.length+1) { 669 return false; 670 } 671 } 672 else if(this.domain){ 673 return false 674 } 675 return true; 676 } 677 678 exports.CookieJar=CookieJar=function CookieJar() { 679 if(this instanceof CookieJar) { 680 var cookies = {} //name: [Cookie] 681 682 this.setCookie = function setCookie(cookie) { 683 cookie = Cookie(cookie); 684 //Delete the cookie if the set is past the current time 685 var remove = cookie.expiration_date <= Date.now(); 686 if(cookie.name in cookies) { 687 var cookies_list = cookies[cookie.name]; 688 for(var i=0;i<cookies_list.length;i++) { 689 var collidable_cookie = cookies_list[i]; 690 if(collidable_cookie.collidesWith(cookie)) { 691 if(remove) { 692 cookies_list.splice(i,1); 693 if(cookies_list.length===0) { 694 delete cookies[cookie.name] 695 } 696 return false; 697 } 698 else { 699 return cookies_list[i]=cookie; 700 } 701 } 702 } 703 if(remove) { 704 return false; 705 } 706 cookies_list.push(cookie); 707 return cookie; 708 } 709 else if(remove){ 710 return false; 711 } 712 else { 713 return cookies[cookie.name]=[cookie]; 714 } 715 } 716 //returns a cookie 717 this.getCookie = function getCookie(cookie_name,access_info) { 718 var cookies_list = cookies[cookie_name]; 719 for(var i=0;i<cookies_list.length;i++) { 720 var cookie = cookies_list[i]; 721 if(cookie.expiration_date <= Date.now()) { 722 if(cookies_list.length===0) { 723 delete cookies[cookie.name] 724 } 725 continue; 726 } 727 if(cookie.matches(access_info)) { 728 return cookie; 729 } 730 } 731 } 732 //returns a list of cookies 733 this.getCookies = function getCookies(access_info) { 734 var matches=[]; 735 for(var cookie_name in cookies) { 736 var cookie=this.getCookie(cookie_name,access_info); 737 if (cookie) { 738 matches.push(cookie); 739 } 740 } 741 matches.toString=function toString(){return matches.join(":");} 742 matches.toValueString=function() {return matches.map(function(c){return c.toValueString();}).join(';');} 743 return matches; 744 } 745 746 return this; 747 } 748 return new CookieJar() 749 } 750 751 752 //returns list of cookies that were set correctly 753 CookieJar.prototype.setCookies = function setCookies(cookies) { 754 cookies=Array.isArray(cookies) 755 ?cookies 756 :cookies.split(cookie_str_splitter); 757 var successful=[] 758 for(var i=0;i<cookies.length;i++) { 759 var cookie = Cookie(cookies[i]); 760 if(this.setCookie(cookie)) { 761 successful.push(cookie); 762 } 763 } 764 return successful; 765 } 766 767 }); 768 769 require.define("/shred/request.js", function (require, module, exports, __dirname, __filename) { 770 // The request object encapsulates a request, creating a Node.js HTTP request and 771 // then handling the response. 772 773 var HTTP = require("http") 774 , HTTPS = require("https") 775 , parseUri = require("./parseUri") 776 , Emitter = require('events').EventEmitter 777 , sprintf = require("sprintf").sprintf 778 , Response = require("./response") 779 , HeaderMixins = require("./mixins/headers") 780 , Content = require("./content") 781 ; 782 783 var STATUS_CODES = HTTP.STATUS_CODES || { 784 100 : 'Continue', 785 101 : 'Switching Protocols', 786 102 : 'Processing', // RFC 2518, obsoleted by RFC 4918 787 200 : 'OK', 788 201 : 'Created', 789 202 : 'Accepted', 790 203 : 'Non-Authoritative Information', 791 204 : 'No Content', 792 205 : 'Reset Content', 793 206 : 'Partial Content', 794 207 : 'Multi-Status', // RFC 4918 795 300 : 'Multiple Choices', 796 301 : 'Moved Permanently', 797 302 : 'Moved Temporarily', 798 303 : 'See Other', 799 304 : 'Not Modified', 800 305 : 'Use Proxy', 801 307 : 'Temporary Redirect', 802 400 : 'Bad Request', 803 401 : 'Unauthorized', 804 402 : 'Payment Required', 805 403 : 'Forbidden', 806 404 : 'Not Found', 807 405 : 'Method Not Allowed', 808 406 : 'Not Acceptable', 809 407 : 'Proxy Authentication Required', 810 408 : 'Request Time-out', 811 409 : 'Conflict', 812 410 : 'Gone', 813 411 : 'Length Required', 814 412 : 'Precondition Failed', 815 413 : 'Request Entity Too Large', 816 414 : 'Request-URI Too Large', 817 415 : 'Unsupported Media Type', 818 416 : 'Requested Range Not Satisfiable', 819 417 : 'Expectation Failed', 820 418 : 'I\'m a teapot', // RFC 2324 821 422 : 'Unprocessable Entity', // RFC 4918 822 423 : 'Locked', // RFC 4918 823 424 : 'Failed Dependency', // RFC 4918 824 425 : 'Unordered Collection', // RFC 4918 825 426 : 'Upgrade Required', // RFC 2817 826 500 : 'Internal Server Error', 827 501 : 'Not Implemented', 828 502 : 'Bad Gateway', 829 503 : 'Service Unavailable', 830 504 : 'Gateway Time-out', 831 505 : 'HTTP Version not supported', 832 506 : 'Variant Also Negotiates', // RFC 2295 833 507 : 'Insufficient Storage', // RFC 4918 834 509 : 'Bandwidth Limit Exceeded', 835 510 : 'Not Extended' // RFC 2774 836 }; 837 838 // The Shred object itself constructs the `Request` object. You should rarely 839 // need to do this directly. 840 841 var Request = function(options) { 842 this.log = options.logger; 843 this.cookieJar = options.cookieJar; 844 this.encoding = options.encoding; 845 this.logCurl = options.logCurl; 846 processOptions(this,options||{}); 847 createRequest(this); 848 }; 849 850 // A `Request` has a number of properties, many of which help with details like 851 // URL parsing or defaulting the port for the request. 852 853 Object.defineProperties(Request.prototype, { 854 855 // - **url**. You can set the `url` property with a valid URL string and all the 856 // URL-related properties (host, port, etc.) will be automatically set on the 857 // request object. 858 859 url: { 860 get: function() { 861 if (!this.scheme) { return null; } 862 return sprintf("%s://%s:%s%s", 863 this.scheme, this.host, this.port, 864 (this.proxy ? "/" : this.path) + 865 (this.query ? ("?" + this.query) : "")); 866 }, 867 set: function(_url) { 868 _url = parseUri(_url); 869 this.scheme = _url.protocol; 870 this.host = _url.host; 871 this.port = _url.port; 872 this.path = _url.path; 873 this.query = _url.query; 874 return this; 875 }, 876 enumerable: true 877 }, 878 879 // - **headers**. Returns a hash representing the request headers. You can't set 880 // this directly, only get it. You can add or modify headers by using the 881 // `setHeader` or `setHeaders` method. This ensures that the headers are 882 // normalized - that is, you don't accidentally send `Content-Type` and 883 // `content-type` headers. Keep in mind that if you modify the returned hash, 884 // it will *not* modify the request headers. 885 886 headers: { 887 get: function() { 888 return this.getHeaders(); 889 }, 890 enumerable: true 891 }, 892 893 // - **port**. Unless you set the `port` explicitly or include it in the URL, it 894 // will default based on the scheme. 895 896 port: { 897 get: function() { 898 if (!this._port) { 899 switch(this.scheme) { 900 case "https": return this._port = 443; 901 case "http": 902 default: return this._port = 80; 903 } 904 } 905 return this._port; 906 }, 907 set: function(value) { this._port = value; return this; }, 908 enumerable: true 909 }, 910 911 // - **method**. The request method - `get`, `put`, `post`, etc. that will be 912 // used to make the request. Defaults to `get`. 913 914 method: { 915 get: function() { 916 return this._method = (this._method||"GET"); 917 }, 918 set: function(value) { 919 this._method = value; return this; 920 }, 921 enumerable: true 922 }, 923 924 // - **query**. Can be set either with a query string or a hash (object). Get 925 // will always return a properly escaped query string or null if there is no 926 // query component for the request. 927 928 query: { 929 get: function() {return this._query;}, 930 set: function(value) { 931 var stringify = function (hash) { 932 var query = ""; 933 for (var key in hash) { 934 query += encodeURIComponent(key) + '=' + encodeURIComponent(hash[key]) + '&'; 935 } 936 // Remove the last '&' 937 query = query.slice(0, -1); 938 return query; 939 } 940 941 if (value) { 942 if (typeof value === 'object') { 943 value = stringify(value); 944 } 945 this._query = value; 946 } else { 947 this._query = ""; 948 } 949 return this; 950 }, 951 enumerable: true 952 }, 953 954 // - **parameters**. This will return the query parameters in the form of a hash 955 // (object). 956 957 parameters: { 958 get: function() { return QueryString.parse(this._query||""); }, 959 enumerable: true 960 }, 961 962 // - **content**. (Aliased as `body`.) Set this to add a content entity to the 963 // request. Attempts to use the `content-type` header to determine what to do 964 // with the content value. Get this to get back a [`Content` 965 // object](./content.html). 966 967 body: { 968 get: function() { return this._body; }, 969 set: function(value) { 970 this._body = new Content({ 971 data: value, 972 type: this.getHeader("Content-Type") 973 }); 974 this.setHeader("Content-Type",this.content.type); 975 this.setHeader("Content-Length",this.content.length); 976 return this; 977 }, 978 enumerable: true 979 }, 980 981 // - **timeout**. Used to determine how long to wait for a response. Does not 982 // distinguish between connect timeouts versus request timeouts. Set either in 983 // milliseconds or with an object with temporal attributes (hours, minutes, 984 // seconds) and convert it into milliseconds. Get will always return 985 // milliseconds. 986 987 timeout: { 988 get: function() { return this._timeout; }, // in milliseconds 989 set: function(timeout) { 990 var request = this 991 , milliseconds = 0; 992 ; 993 if (!timeout) return this; 994 if (typeof timeout==="number") { milliseconds = timeout; } 995 else { 996 milliseconds = (timeout.milliseconds||0) + 997 (1000 * ((timeout.seconds||0) + 998 (60 * ((timeout.minutes||0) + 999 (60 * (timeout.hours||0)))))); 1000 } 1001 this._timeout = milliseconds; 1002 return this; 1003 }, 1004 enumerable: true 1005 } 1006 }); 1007 1008 // Alias `body` property to `content`. Since the [content object](./content.html) 1009 // has a `body` attribute, it's preferable to use `content` since you can then 1010 // access the raw content data using `content.body`. 1011 1012 Object.defineProperty(Request.prototype,"content", 1013 Object.getOwnPropertyDescriptor(Request.prototype, "body")); 1014 1015 // The `Request` object can be pretty overwhelming to view using the built-in 1016 // Node.js inspect method. We want to make it a bit more manageable. This 1017 // probably goes [too far in the other 1018 // direction](https://github.com/spire-io/shred/issues/2). 1019 1020 Request.prototype.inspect = function () { 1021 var request = this; 1022 var headers = this.format_headers(); 1023 var summary = ["<Shred Request> ", request.method.toUpperCase(), 1024 request.url].join(" ") 1025 return [ summary, "- Headers:", headers].join("\n"); 1026 }; 1027 1028 Request.prototype.format_headers = function () { 1029 var array = [] 1030 var headers = this._headers 1031 for (var key in headers) { 1032 if (headers.hasOwnProperty(key)) { 1033 var value = headers[key] 1034 array.push("\t" + key + ": " + value); 1035 } 1036 } 1037 return array.join("\n"); 1038 }; 1039 1040 // Allow chainable 'on's: shred.get({ ... }).on( ... ). You can pass in a 1041 // single function, a pair (event, function), or a hash: 1042 // { event: function, event: function } 1043 Request.prototype.on = function (eventOrHash, listener) { 1044 var emitter = this.emitter; 1045 // Pass in a single argument as a function then make it the default response handler 1046 if (arguments.length === 1 && typeof(eventOrHash) === 'function') { 1047 emitter.on('response', eventOrHash); 1048 } else if (arguments.length === 1 && typeof(eventOrHash) === 'object') { 1049 for (var key in eventOrHash) { 1050 if (eventOrHash.hasOwnProperty(key)) { 1051 emitter.on(key, eventOrHash[key]); 1052 } 1053 } 1054 } else { 1055 emitter.on(eventOrHash, listener); 1056 } 1057 return this; 1058 }; 1059 1060 // Add in the header methods. Again, these ensure we don't get the same header 1061 // multiple times with different case conventions. 1062 HeaderMixins.gettersAndSetters(Request); 1063 1064 // `processOptions` is called from the constructor to handle all the work 1065 // associated with making sure we do our best to ensure we have a valid request. 1066 1067 var processOptions = function(request,options) { 1068 1069 request.log.debug("Processing request options .."); 1070 1071 // We'll use `request.emitter` to manage the `on` event handlers. 1072 request.emitter = (new Emitter); 1073 1074 request.agent = options.agent; 1075 1076 // Set up the handlers ... 1077 if (options.on) { 1078 for (var key in options.on) { 1079 if (options.on.hasOwnProperty(key)) { 1080 request.emitter.on(key, options.on[key]); 1081 } 1082 } 1083 } 1084 1085 // Make sure we were give a URL or a host 1086 if (!options.url && !options.host) { 1087 request.emitter.emit("request_error", 1088 new Error("No url or url options (host, port, etc.)")); 1089 return; 1090 } 1091 1092 // Allow for the [use of a proxy](http://www.jmarshall.com/easy/http/#proxies). 1093 1094 if (options.url) { 1095 if (options.proxy) { 1096 request.url = options.proxy; 1097 request.path = options.url; 1098 } else { 1099 request.url = options.url; 1100 } 1101 } 1102 1103 // Set the remaining options. 1104 request.query = options.query||options.parameters||request.query ; 1105 request.method = options.method; 1106 request.setHeader("user-agent",options.agent||"Shred"); 1107 request.setHeaders(options.headers); 1108 1109 if (request.cookieJar) { 1110 var cookies = request.cookieJar.getCookies( CookieAccessInfo( request.host, request.path ) ); 1111 if (cookies.length) { 1112 var cookieString = request.getHeader('cookie')||''; 1113 for (var cookieIndex = 0; cookieIndex < cookies.length; ++cookieIndex) { 1114 if ( cookieString.length && cookieString[ cookieString.length - 1 ] != ';' ) 1115 { 1116 cookieString += ';'; 1117 } 1118 cookieString += cookies[ cookieIndex ].name + '=' + cookies[ cookieIndex ].value + ';'; 1119 } 1120 request.setHeader("cookie", cookieString); 1121 } 1122 } 1123 1124 // The content entity can be set either using the `body` or `content` attributes. 1125 if (options.body||options.content) { 1126 request.content = options.body||options.content; 1127 } 1128 request.timeout = options.timeout; 1129 1130 }; 1131 1132 // `createRequest` is also called by the constructor, after `processOptions`. 1133 // This actually makes the request and processes the response, so `createRequest` 1134 // is a bit of a misnomer. 1135 1136 var createRequest = function(request) { 1137 var timeout ; 1138 1139 request.log.debug("Creating request .."); 1140 request.log.debug(request); 1141 1142 var reqParams = { 1143 host: request.host, 1144 port: request.port, 1145 method: request.method, 1146 path: request.path + (request.query ? '?'+request.query : ""), 1147 headers: request.getHeaders(), 1148 // Node's HTTP/S modules will ignore this, but we are using the 1149 // browserify-http module in the browser for both HTTP and HTTPS, and this 1150 // is how you differentiate the two. 1151 scheme: request.scheme, 1152 // Use a provided agent. 'Undefined' is the default, which uses a global 1153 // agent. 1154 agent: request.agent 1155 }; 1156 1157 if (request.logCurl) { 1158 logCurl(request); 1159 } 1160 1161 var http = request.scheme == "http" ? HTTP : HTTPS; 1162 1163 // Set up the real request using the selected library. The request won't be 1164 // sent until we call `.end()`. 1165 request._raw = http.request(reqParams, function(response) { 1166 request.log.debug("Received response .."); 1167 1168 // We haven't timed out and we have a response, so make sure we clear the 1169 // timeout so it doesn't fire while we're processing the response. 1170 clearTimeout(timeout); 1171 1172 // Construct a Shred `Response` object from the response. This will stream 1173 // the response, thus the need for the callback. We can access the response 1174 // entity safely once we're in the callback. 1175 response = new Response(response, request, function(response) { 1176 1177 // Set up some event magic. The precedence is given first to 1178 // status-specific handlers, then to responses for a given event, and then 1179 // finally to the more general `response` handler. In the last case, we 1180 // need to first make sure we're not dealing with a a redirect. 1181 var emit = function(event) { 1182 var emitter = request.emitter; 1183 var textStatus = STATUS_CODES[response.status] ? STATUS_CODES[response.status].toLowerCase() : null; 1184 if (emitter.listeners(response.status).length > 0 || emitter.listeners(textStatus).length > 0) { 1185 emitter.emit(response.status, response); 1186 emitter.emit(textStatus, response); 1187 } else { 1188 if (emitter.listeners(event).length>0) { 1189 emitter.emit(event, response); 1190 } else if (!response.isRedirect) { 1191 emitter.emit("response", response); 1192 //console.warn("Request has no event listener for status code " + response.status); 1193 } 1194 } 1195 }; 1196 1197 // Next, check for a redirect. We simply repeat the request with the URL 1198 // given in the `Location` header. We fire a `redirect` event. 1199 if (response.isRedirect) { 1200 request.log.debug("Redirecting to " 1201 + response.getHeader("Location")); 1202 request.url = response.getHeader("Location"); 1203 emit("redirect"); 1204 createRequest(request); 1205 1206 // Okay, it's not a redirect. Is it an error of some kind? 1207 } else if (response.isError) { 1208 emit("error"); 1209 } else { 1210 // It looks like we're good shape. Trigger the `success` event. 1211 emit("success"); 1212 } 1213 }); 1214 }); 1215 1216 // We're still setting up the request. Next, we're going to handle error cases 1217 // where we have no response. We don't emit an error event because that event 1218 // takes a response. We don't response handlers to have to check for a null 1219 // value. However, we [should introduce a different event 1220 // type](https://github.com/spire-io/shred/issues/3) for this type of error. 1221 request._raw.on("error", function(error) { 1222 request.emitter.emit("request_error", error); 1223 }); 1224 1225 request._raw.on("socket", function(socket) { 1226 request.emitter.emit("socket", socket); 1227 }); 1228 1229 // TCP timeouts should also trigger the "response_error" event. 1230 request._raw.on('socket', function () { 1231 request._raw.socket.on('timeout', function () { 1232 // This should trigger the "error" event on the raw request, which will 1233 // trigger the "response_error" on the shred request. 1234 request._raw.abort(); 1235 }); 1236 }); 1237 1238 1239 // We're almost there. Next, we need to write the request entity to the 1240 // underlying request object. 1241 if (request.content) { 1242 request.log.debug("Streaming body: '" + 1243 request.content.data.slice(0,59) + "' ... "); 1244 request._raw.write(request.content.data); 1245 } 1246 1247 // Finally, we need to set up the timeout. We do this last so that we don't 1248 // start the clock ticking until the last possible moment. 1249 if (request.timeout) { 1250 timeout = setTimeout(function() { 1251 request.log.debug("Timeout fired, aborting request ..."); 1252 request._raw.abort(); 1253 request.emitter.emit("timeout", request); 1254 },request.timeout); 1255 } 1256 1257 // The `.end()` method will cause the request to fire. Technically, it might 1258 // have already sent the headers and body. 1259 request.log.debug("Sending request ..."); 1260 request._raw.end(); 1261 }; 1262 1263 // Logs the curl command for the request. 1264 var logCurl = function (req) { 1265 var headers = req.getHeaders(); 1266 var headerString = ""; 1267 1268 for (var key in headers) { 1269 headerString += '-H "' + key + ": " + headers[key] + '" '; 1270 } 1271 1272 var bodyString = "" 1273 1274 if (req.content) { 1275 bodyString += "-d '" + req.content.body + "' "; 1276 } 1277 1278 var query = req.query ? '?' + req.query : ""; 1279 1280 console.log("curl " + 1281 "-X " + req.method.toUpperCase() + " " + 1282 req.scheme + "://" + req.host + ":" + req.port + req.path + query + " " + 1283 headerString + 1284 bodyString 1285 ); 1286 }; 1287 1288 1289 module.exports = Request; 1290 1291 }); 1292 1293 require.define("http", function (require, module, exports, __dirname, __filename) { 1294 // todo 1295 1296 }); 1297 1298 require.define("https", function (require, module, exports, __dirname, __filename) { 1299 // todo 1300 1301 }); 1302 1303 require.define("/shred/parseUri.js", function (require, module, exports, __dirname, __filename) { 1304 // parseUri 1.2.2 1305 // (c) Steven Levithan <stevenlevithan.com> 1306 // MIT License 1307 1308 function parseUri (str) { 1309 var o = parseUri.options, 1310 m = o.parser[o.strictMode ? "strict" : "loose"].exec(str), 1311 uri = {}, 1312 i = 14; 1313 1314 while (i--) uri[o.key[i]] = m[i] || ""; 1315 1316 uri[o.q.name] = {}; 1317 uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) { 1318 if ($1) uri[o.q.name][$1] = $2; 1319 }); 1320 1321 return uri; 1322 }; 1323 1324 parseUri.options = { 1325 strictMode: false, 1326 key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"], 1327 q: { 1328 name: "queryKey", 1329 parser: /(?:^|&)([^&=]*)=?([^&]*)/g 1330 }, 1331 parser: { 1332 strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/, 1333 loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/ 1334 } 1335 }; 1336 1337 module.exports = parseUri; 1338 1339 }); 1340 1341 require.define("events", function (require, module, exports, __dirname, __filename) { 1342 if (!process.EventEmitter) process.EventEmitter = function () {}; 1343 1344 var EventEmitter = exports.EventEmitter = process.EventEmitter; 1345 var isArray = typeof Array.isArray === 'function' 1346 ? Array.isArray 1347 : function (xs) { 1348 return Object.toString.call(xs) === '[object Array]' 1349 } 1350 ; 1351 1352 // By default EventEmitters will print a warning if more than 1353 // 10 listeners are added to it. This is a useful default which 1354 // helps finding memory leaks. 1355 // 1356 // Obviously not all Emitters should be limited to 10. This function allows 1357 // that to be increased. Set to zero for unlimited. 1358 var defaultMaxListeners = 10; 1359 EventEmitter.prototype.setMaxListeners = function(n) { 1360 if (!this._events) this._events = {}; 1361 this._events.maxListeners = n; 1362 }; 1363 1364 1365 EventEmitter.prototype.emit = function(type) { 1366 // If there is no 'error' event listener then throw. 1367 if (type === 'error') { 1368 if (!this._events || !this._events.error || 1369 (isArray(this._events.error) && !this._events.error.length)) 1370 { 1371 if (arguments[1] instanceof Error) { 1372 throw arguments[1]; // Unhandled 'error' event 1373 } else { 1374 throw new Error("Uncaught, unspecified 'error' event."); 1375 } 1376 return false; 1377 } 1378 } 1379 1380 if (!this._events) return false; 1381 var handler = this._events[type]; 1382 if (!handler) return false; 1383 1384 if (typeof handler == 'function') { 1385 switch (arguments.length) { 1386 // fast cases 1387 case 1: 1388 handler.call(this); 1389 break; 1390 case 2: 1391 handler.call(this, arguments[1]); 1392 break; 1393 case 3: 1394 handler.call(this, arguments[1], arguments[2]); 1395 break; 1396 // slower 1397 default: 1398 var args = Array.prototype.slice.call(arguments, 1); 1399 handler.apply(this, args); 1400 } 1401 return true; 1402 1403 } else if (isArray(handler)) { 1404 var args = Array.prototype.slice.call(arguments, 1); 1405 1406 var listeners = handler.slice(); 1407 for (var i = 0, l = listeners.length; i < l; i++) { 1408 listeners[i].apply(this, args); 1409 } 1410 return true; 1411 1412 } else { 1413 return false; 1414 } 1415 }; 1416 1417 // EventEmitter is defined in src/node_events.cc 1418 // EventEmitter.prototype.emit() is also defined there. 1419 EventEmitter.prototype.addListener = function(type, listener) { 1420 if ('function' !== typeof listener) { 1421 throw new Error('addListener only takes instances of Function'); 1422 } 1423 1424 if (!this._events) this._events = {}; 1425 1426 // To avoid recursion in the case that type == "newListeners"! Before 1427 // adding it to the listeners, first emit "newListeners". 1428 this.emit('newListener', type, listener); 1429 1430 if (!this._events[type]) { 1431 // Optimize the case of one listener. Don't need the extra array object. 1432 this._events[type] = listener; 1433 } else if (isArray(this._events[type])) { 1434 1435 // Check for listener leak 1436 if (!this._events[type].warned) { 1437 var m; 1438 if (this._events.maxListeners !== undefined) { 1439 m = this._events.maxListeners; 1440 } else { 1441 m = defaultMaxListeners; 1442 } 1443 1444 if (m && m > 0 && this._events[type].length > m) { 1445 this._events[type].warned = true; 1446 console.error('(node) warning: possible EventEmitter memory ' + 1447 'leak detected. %d listeners added. ' + 1448 'Use emitter.setMaxListeners() to increase limit.', 1449 this._events[type].length); 1450 console.trace(); 1451 } 1452 } 1453 1454 // If we've already got an array, just append. 1455 this._events[type].push(listener); 1456 } else { 1457 // Adding the second element, need to change to array. 1458 this._events[type] = [this._events[type], listener]; 1459 } 1460 1461 return this; 1462 }; 1463 1464 EventEmitter.prototype.on = EventEmitter.prototype.addListener; 1465 1466 EventEmitter.prototype.once = function(type, listener) { 1467 var self = this; 1468 self.on(type, function g() { 1469 self.removeListener(type, g); 1470 listener.apply(this, arguments); 1471 }); 1472 1473 return this; 1474 }; 1475 1476 EventEmitter.prototype.removeListener = function(type, listener) { 1477 if ('function' !== typeof listener) { 1478 throw new Error('removeListener only takes instances of Function'); 1479 } 1480 1481 // does not use listeners(), so no side effect of creating _events[type] 1482 if (!this._events || !this._events[type]) return this; 1483 1484 var list = this._events[type]; 1485 1486 if (isArray(list)) { 1487 var i = list.indexOf(listener); 1488 if (i < 0) return this; 1489 list.splice(i, 1); 1490 if (list.length == 0) 1491 delete this._events[type]; 1492 } else if (this._events[type] === listener) { 1493 delete this._events[type]; 1494 } 1495 1496 return this; 1497 }; 1498 1499 EventEmitter.prototype.removeAllListeners = function(type) { 1500 // does not use listeners(), so no side effect of creating _events[type] 1501 if (type && this._events && this._events[type]) this._events[type] = null; 1502 return this; 1503 }; 1504 1505 EventEmitter.prototype.listeners = function(type) { 1506 if (!this._events) this._events = {}; 1507 if (!this._events[type]) this._events[type] = []; 1508 if (!isArray(this._events[type])) { 1509 this._events[type] = [this._events[type]]; 1510 } 1511 return this._events[type]; 1512 }; 1513 1514 }); 1515 1516 require.define("/node_modules/sprintf/package.json", function (require, module, exports, __dirname, __filename) { 1517 module.exports = {"main":"./lib/sprintf"} 1518 }); 1519 1520 require.define("/node_modules/sprintf/lib/sprintf.js", function (require, module, exports, __dirname, __filename) { 1521 /** 1522 sprintf() for JavaScript 0.7-beta1 1523 http://www.diveintojavascript.com/projects/javascript-sprintf 1524 1525 Copyright (c) Alexandru Marasteanu <alexaholic [at) gmail (dot] com> 1526 All rights reserved. 1527 1528 Redistribution and use in source and binary forms, with or without 1529 modification, are permitted provided that the following conditions are met: 1530 * Redistributions of source code must retain the above copyright 1531 notice, this list of conditions and the following disclaimer. 1532 * Redistributions in binary form must reproduce the above copyright 1533 notice, this list of conditions and the following disclaimer in the 1534 documentation and/or other materials provided with the distribution. 1535 * Neither the name of sprintf() for JavaScript nor the 1536 names of its contributors may be used to endorse or promote products 1537 derived from this software without specific prior written permission. 1538 1539 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 1540 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 1541 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 1542 DISCLAIMED. IN NO EVENT SHALL Alexandru Marasteanu BE LIABLE FOR ANY 1543 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 1544 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 1545 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 1546 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1547 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 1548 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1549 1550 1551 Changelog: 1552 2010.11.07 - 0.7-beta1-node 1553 - converted it to a node.js compatible module 1554 1555 2010.09.06 - 0.7-beta1 1556 - features: vsprintf, support for named placeholders 1557 - enhancements: format cache, reduced global namespace pollution 1558 1559 2010.05.22 - 0.6: 1560 - reverted to 0.4 and fixed the bug regarding the sign of the number 0 1561 Note: 1562 Thanks to Raphael Pigulla <raph (at] n3rd [dot) org> (http://www.n3rd.org/) 1563 who warned me about a bug in 0.5, I discovered that the last update was 1564 a regress. I appologize for that. 1565 1566 2010.05.09 - 0.5: 1567 - bug fix: 0 is now preceeded with a + sign 1568 - bug fix: the sign was not at the right position on padded results (Kamal Abdali) 1569 - switched from GPL to BSD license 1570 1571 2007.10.21 - 0.4: 1572 - unit test and patch (David Baird) 1573 1574 2007.09.17 - 0.3: 1575 - bug fix: no longer throws exception on empty paramenters (Hans Pufal) 1576 1577 2007.09.11 - 0.2: 1578 - feature: added argument swapping 1579 1580 2007.04.03 - 0.1: 1581 - initial release 1582 **/ 1583 1584 var sprintf = (function() { 1585 function get_type(variable) { 1586 return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); 1587 } 1588 function str_repeat(input, multiplier) { 1589 for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */} 1590 return output.join(''); 1591 } 1592 1593 var str_format = function() { 1594 if (!str_format.cache.hasOwnProperty(arguments[0])) { 1595 str_format.cache[arguments[0]] = str_format.parse(arguments[0]); 1596 } 1597 return str_format.format.call(null, str_format.cache[arguments[0]], arguments); 1598 }; 1599 1600 str_format.format = function(parse_tree, argv) { 1601 var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; 1602 for (i = 0; i < tree_length; i++) { 1603 node_type = get_type(parse_tree[i]); 1604 if (node_type === 'string') { 1605 output.push(parse_tree[i]); 1606 } 1607 else if (node_type === 'array') { 1608 match = parse_tree[i]; // convenience purposes only 1609 if (match[2]) { // keyword argument 1610 arg = argv[cursor]; 1611 for (k = 0; k < match[2].length; k++) { 1612 if (!arg.hasOwnProperty(match[2][k])) { 1613 throw(sprintf('[sprintf] property "%s" does not exist', match[2][k])); 1614 } 1615 arg = arg[match[2][k]]; 1616 } 1617 } 1618 else if (match[1]) { // positional argument (explicit) 1619 arg = argv[match[1]]; 1620 } 1621 else { // positional argument (implicit) 1622 arg = argv[cursor++]; 1623 } 1624 1625 if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { 1626 throw(sprintf('[sprintf] expecting number but found %s', get_type(arg))); 1627 } 1628 switch (match[8]) { 1629 case 'b': arg = arg.toString(2); break; 1630 case 'c': arg = String.fromCharCode(arg); break; 1631 case 'd': arg = parseInt(arg, 10); break; 1632 case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; 1633 case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; 1634 case 'o': arg = arg.toString(8); break; 1635 case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; 1636 case 'u': arg = Math.abs(arg); break; 1637 case 'x': arg = arg.toString(16); break; 1638 case 'X': arg = arg.toString(16).toUpperCase(); break; 1639 } 1640 arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); 1641 pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; 1642 pad_length = match[6] - String(arg).length; 1643 pad = match[6] ? str_repeat(pad_character, pad_length) : ''; 1644 output.push(match[5] ? arg + pad : pad + arg); 1645 } 1646 } 1647 return output.join(''); 1648 }; 1649 1650 str_format.cache = {}; 1651 1652 str_format.parse = function(fmt) { 1653 var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; 1654 while (_fmt) { 1655 if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { 1656 parse_tree.push(match[0]); 1657 } 1658 else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { 1659 parse_tree.push('%'); 1660 } 1661 else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { 1662 if (match[2]) { 1663 arg_names |= 1; 1664 var field_list = [], replacement_field = match[2], field_match = []; 1665 if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { 1666 field_list.push(field_match[1]); 1667 while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { 1668 if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { 1669 field_list.push(field_match[1]); 1670 } 1671 else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { 1672 field_list.push(field_match[1]); 1673 } 1674 else { 1675 throw('[sprintf] huh?'); 1676 } 1677 } 1678 } 1679 else { 1680 throw('[sprintf] huh?'); 1681 } 1682 match[2] = field_list; 1683 } 1684 else { 1685 arg_names |= 2; 1686 } 1687 if (arg_names === 3) { 1688 throw('[sprintf] mixing positional and named placeholders is not (yet) supported'); 1689 } 1690 parse_tree.push(match); 1691 } 1692 else { 1693 throw('[sprintf] huh?'); 1694 } 1695 _fmt = _fmt.substring(match[0].length); 1696 } 1697 return parse_tree; 1698 }; 1699 1700 return str_format; 1701 })(); 1702 1703 var vsprintf = function(fmt, argv) { 1704 argv.unshift(fmt); 1705 return sprintf.apply(null, argv); 1706 }; 1707 1708 exports.sprintf = sprintf; 1709 exports.vsprintf = vsprintf; 1710 }); 1711 1712 require.define("/shred/response.js", function (require, module, exports, __dirname, __filename) { 1713 // The `Response object` encapsulates a Node.js HTTP response. 1714 1715 var Content = require("./content") 1716 , HeaderMixins = require("./mixins/headers") 1717 , CookieJarLib = require( "cookiejar" ) 1718 , Cookie = CookieJarLib.Cookie 1719 ; 1720 1721 // Browser doesn't have zlib. 1722 var zlib = null; 1723 try { 1724 zlib = require('zlib'); 1725 } catch (e) { 1726 // console.warn("no zlib library"); 1727 } 1728 1729 // Iconv doesn't work in browser 1730 var Iconv = null; 1731 try { 1732 Iconv = require('iconv-lite'); 1733 } catch (e) { 1734 // console.warn("no iconv library"); 1735 } 1736 1737 // Construct a `Response` object. You should never have to do this directly. The 1738 // `Request` object handles this, getting the raw response object and passing it 1739 // in here, along with the request. The callback allows us to stream the response 1740 // and then use the callback to let the request know when it's ready. 1741 var Response = function(raw, request, callback) { 1742 var response = this; 1743 this._raw = raw; 1744 1745 // The `._setHeaders` method is "private"; you can't otherwise set headers on 1746 // the response. 1747 this._setHeaders.call(this,raw.headers); 1748 1749 // store any cookies 1750 if (request.cookieJar && this.getHeader('set-cookie')) { 1751 var cookieStrings = this.getHeader('set-cookie'); 1752 var cookieObjs = [] 1753 , cookie; 1754 1755 for (var i = 0; i < cookieStrings.length; i++) { 1756 var cookieString = cookieStrings[i]; 1757 if (!cookieString) { 1758 continue; 1759 } 1760 1761 if (!cookieString.match(/domain\=/i)) { 1762 cookieString += '; domain=' + request.host; 1763 } 1764 1765 if (!cookieString.match(/path\=/i)) { 1766 cookieString += '; path=' + request.path; 1767 } 1768 1769 try { 1770 cookie = new Cookie(cookieString); 1771 if (cookie) { 1772 cookieObjs.push(cookie); 1773 } 1774 } catch (e) { 1775 console.warn("Tried to set bad cookie: " + cookieString); 1776 } 1777 } 1778 1779 request.cookieJar.setCookies(cookieObjs); 1780 } 1781 1782 this.request = request; 1783 this.client = request.client; 1784 this.log = this.request.log; 1785 1786 // Stream the response content entity and fire the callback when we're done. 1787 // Store the incoming data in a array of Buffers which we concatinate into one 1788 // buffer at the end. We need to use buffers instead of strings here in order 1789 // to preserve binary data. 1790 var chunkBuffers = []; 1791 var dataLength = 0; 1792 raw.on("data", function(chunk) { 1793 chunkBuffers.push(chunk); 1794 dataLength += chunk.length; 1795 }); 1796 raw.on("end", function() { 1797 var body; 1798 if (typeof Buffer === 'undefined') { 1799 // Just concatinate into a string 1800 body = chunkBuffers.join(''); 1801 } else { 1802 // Initialize new buffer and add the chunks one-at-a-time. 1803 body = new Buffer(dataLength); 1804 for (var i = 0, pos = 0; i < chunkBuffers.length; i++) { 1805 chunkBuffers[i].copy(body, pos); 1806 pos += chunkBuffers[i].length; 1807 } 1808 } 1809 1810 var setBodyAndFinish = function (body) { 1811 response._body = new Content({ 1812 body: body, 1813 type: response.getHeader("Content-Type") 1814 }); 1815 callback(response); 1816 } 1817 1818 if (zlib && response.getHeader("Content-Encoding") === 'gzip'){ 1819 zlib.gunzip(body, function (err, gunzippedBody) { 1820 if (Iconv && response.request.encoding){ 1821 body = Iconv.fromEncoding(gunzippedBody,response.request.encoding); 1822 } else { 1823 body = gunzippedBody.toString(); 1824 } 1825 setBodyAndFinish(body); 1826 }) 1827 } 1828 else{ 1829 if (response.request.encoding){ 1830 body = Iconv.fromEncoding(body,response.request.encoding); 1831 } 1832 setBodyAndFinish(body); 1833 } 1834 }); 1835 }; 1836 1837 // The `Response` object can be pretty overwhelming to view using the built-in 1838 // Node.js inspect method. We want to make it a bit more manageable. This 1839 // probably goes [too far in the other 1840 // direction](https://github.com/spire-io/shred/issues/2). 1841 1842 Response.prototype = { 1843 inspect: function() { 1844 var response = this; 1845 var headers = this.format_headers(); 1846 var summary = ["<Shred Response> ", response.status].join(" ") 1847 return [ summary, "- Headers:", headers].join("\n"); 1848 }, 1849 format_headers: function () { 1850 var array = [] 1851 var headers = this._headers 1852 for (var key in headers) { 1853 if (headers.hasOwnProperty(key)) { 1854 var value = headers[key] 1855 array.push("\t" + key + ": " + value); 1856 } 1857 } 1858 return array.join("\n"); 1859 } 1860 }; 1861 1862 // `Response` object properties, all of which are read-only: 1863 Object.defineProperties(Response.prototype, { 1864 1865 // - **status**. The HTTP status code for the response. 1866 status: { 1867 get: function() { return this._raw.statusCode; }, 1868 enumerable: true 1869 }, 1870 1871 // - **content**. The HTTP content entity, if any. Provided as a [content 1872 // object](./content.html), which will attempt to convert the entity based upon 1873 // the `content-type` header. The converted value is available as 1874 // `content.data`. The original raw content entity is available as 1875 // `content.body`. 1876 body: { 1877 get: function() { return this._body; } 1878 }, 1879 content: { 1880 get: function() { return this.body; }, 1881 enumerable: true 1882 }, 1883 1884 // - **isRedirect**. Is the response a redirect? These are responses with 3xx 1885 // status and a `Location` header. 1886 isRedirect: { 1887 get: function() { 1888 return (this.status>299 1889 &&this.status<400 1890 &&this.getHeader("Location")); 1891 }, 1892 enumerable: true 1893 }, 1894 1895 // - **isError**. Is the response an error? These are responses with status of 1896 // 400 or greater. 1897 isError: { 1898 get: function() { 1899 return (this.status === 0 || this.status > 399) 1900 }, 1901 enumerable: true 1902 } 1903 }); 1904 1905 // Add in the [getters for accessing the normalized headers](./headers.js). 1906 HeaderMixins.getters(Response); 1907 HeaderMixins.privateSetters(Response); 1908 1909 // Work around Mozilla bug #608735 [https://bugzil.la/608735], which causes 1910 // getAllResponseHeaders() to return {} if the response is a CORS request. 1911 // xhr.getHeader still works correctly. 1912 var getHeader = Response.prototype.getHeader; 1913 Response.prototype.getHeader = function (name) { 1914 return (getHeader.call(this,name) || 1915 (typeof this._raw.getHeader === 'function' && this._raw.getHeader(name))); 1916 }; 1917 1918 module.exports = Response; 1919 1920 }); 1921 1922 require.define("/shred/content.js", function (require, module, exports, __dirname, __filename) { 1923 1924 // The purpose of the `Content` object is to abstract away the data conversions 1925 // to and from raw content entities as strings. For example, you want to be able 1926 // to pass in a Javascript object and have it be automatically converted into a 1927 // JSON string if the `content-type` is set to a JSON-based media type. 1928 // Conversely, you want to be able to transparently get back a Javascript object 1929 // in the response if the `content-type` is a JSON-based media-type. 1930 1931 // One limitation of the current implementation is that it [assumes the `charset` is UTF-8](https://github.com/spire-io/shred/issues/5). 1932 1933 // The `Content` constructor takes an options object, which *must* have either a 1934 // `body` or `data` property and *may* have a `type` property indicating the 1935 // media type. If there is no `type` attribute, a default will be inferred. 1936 var Content = function(options) { 1937 this.body = options.body; 1938 this.data = options.data; 1939 this.type = options.type; 1940 }; 1941 1942 Content.prototype = { 1943 // Treat `toString()` as asking for the `content.body`. That is, the raw content entity. 1944 // 1945 // toString: function() { return this.body; } 1946 // 1947 // Commented out, but I've forgotten why. :/ 1948 }; 1949 1950 1951 // `Content` objects have the following attributes: 1952 Object.defineProperties(Content.prototype,{ 1953 1954 // - **type**. Typically accessed as `content.type`, reflects the `content-type` 1955 // header associated with the request or response. If not passed as an options 1956 // to the constructor or set explicitly, it will infer the type the `data` 1957 // attribute, if possible, and, failing that, will default to `text/plain`. 1958 type: { 1959 get: function() { 1960 if (this._type) { 1961 return this._type; 1962 } else { 1963 if (this._data) { 1964 switch(typeof this._data) { 1965 case "string": return "text/plain"; 1966 case "object": return "application/json"; 1967 } 1968 } 1969 } 1970 return "text/plain"; 1971 }, 1972 set: function(value) { 1973 this._type = value; 1974 return this; 1975 }, 1976 enumerable: true 1977 }, 1978 1979 // - **data**. Typically accessed as `content.data`, reflects the content entity 1980 // converted into Javascript data. This can be a string, if the `type` is, say, 1981 // `text/plain`, but can also be a Javascript object. The conversion applied is 1982 // based on the `processor` attribute. The `data` attribute can also be set 1983 // directly, in which case the conversion will be done the other way, to infer 1984 // the `body` attribute. 1985 data: { 1986 get: function() { 1987 if (this._body) { 1988 return this.processor.parser(this._body); 1989 } else { 1990 return this._data; 1991 } 1992 }, 1993 set: function(data) { 1994 if (this._body&&data) Errors.setDataWithBody(this); 1995 this._data = data; 1996 return this; 1997 }, 1998 enumerable: true 1999 }, 2000 2001 // - **body**. Typically accessed as `content.body`, reflects the content entity 2002 // as a UTF-8 string. It is the mirror of the `data` attribute. If you set the 2003 // `data` attribute, the `body` attribute will be inferred and vice-versa. If 2004 // you attempt to set both, an exception is raised. 2005 body: { 2006 get: function() { 2007 if (this._data) { 2008 return this.processor.stringify(this._data); 2009 } else { 2010 return this.processor.stringify(this._body); 2011 } 2012 }, 2013 set: function(body) { 2014 if (this._data&&body) Errors.setBodyWithData(this); 2015 this._body = body; 2016 return this; 2017 }, 2018 enumerable: true 2019 }, 2020 2021 // - **processor**. The functions that will be used to convert to/from `data` and 2022 // `body` attributes. You can add processors. The two that are built-in are for 2023 // `text/plain`, which is basically an identity transformation and 2024 // `application/json` and other JSON-based media types (including custom media 2025 // types with `+json`). You can add your own processors. See below. 2026 processor: { 2027 get: function() { 2028 var processor = Content.processors[this.type]; 2029 if (processor) { 2030 return processor; 2031 } else { 2032 // Return the first processor that matches any part of the 2033 // content type. ex: application/vnd.foobar.baz+json will match json. 2034 var main = this.type.split(";")[0]; 2035 var parts = main.split(/\+|\//); 2036 for (var i=0, l=parts.length; i < l; i++) { 2037 processor = Content.processors[parts[i]] 2038 } 2039 return processor || {parser:identity,stringify:toString}; 2040 } 2041 }, 2042 enumerable: true 2043 }, 2044 2045 // - **length**. Typically accessed as `content.length`, returns the length in 2046 // bytes of the raw content entity. 2047 length: { 2048 get: function() { 2049 if (typeof Buffer !== 'undefined') { 2050 return Buffer.byteLength(this.body); 2051 } 2052 return this.body.length; 2053 } 2054 } 2055 }); 2056 2057 Content.processors = {}; 2058 2059 // The `registerProcessor` function allows you to add your own processors to 2060 // convert content entities. Each processor consists of a Javascript object with 2061 // two properties: 2062 // - **parser**. The function used to parse a raw content entity and convert it 2063 // into a Javascript data type. 2064 // - **stringify**. The function used to convert a Javascript data type into a 2065 // raw content entity. 2066 Content.registerProcessor = function(types,processor) { 2067 2068 // You can pass an array of types that will trigger this processor, or just one. 2069 // We determine the array via duck-typing here. 2070 if (types.forEach) { 2071 types.forEach(function(type) { 2072 Content.processors[type] = processor; 2073 }); 2074 } else { 2075 // If you didn't pass an array, we just use what you pass in. 2076 Content.processors[types] = processor; 2077 } 2078 }; 2079 2080 // Register the identity processor, which is used for text-based media types. 2081 var identity = function(x) { return x; } 2082 , toString = function(x) { return x.toString(); } 2083 Content.registerProcessor( 2084 ["text/html","text/plain","text"], 2085 { parser: identity, stringify: toString }); 2086 2087 // Register the JSON processor, which is used for JSON-based media types. 2088 Content.registerProcessor( 2089 ["application/json; charset=utf-8","application/json","json"], 2090 { 2091 parser: function(string) { 2092 return JSON.parse(string); 2093 }, 2094 stringify: function(data) { 2095 return JSON.stringify(data); }}); 2096 2097 // Error functions are defined separately here in an attempt to make the code 2098 // easier to read. 2099 var Errors = { 2100 setDataWithBody: function(object) { 2101 throw new Error("Attempt to set data attribute of a content object " + 2102 "when the body attributes was already set."); 2103 }, 2104 setBodyWithData: function(object) { 2105 throw new Error("Attempt to set body attribute of a content object " + 2106 "when the data attributes was already set."); 2107 } 2108 } 2109 module.exports = Content; 2110 2111 }); 2112 2113 require.define("/shred/mixins/headers.js", function (require, module, exports, __dirname, __filename) { 2114 // The header mixins allow you to add HTTP header support to any object. This 2115 // might seem pointless: why not simply use a hash? The main reason is that, per 2116 // the [HTTP spec](http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2), 2117 // headers are case-insensitive. So, for example, `content-type` is the same as 2118 // `CONTENT-TYPE` which is the same as `Content-Type`. Since there is no way to 2119 // overload the index operator in Javascript, using a hash to represent the 2120 // headers means it's possible to have two conflicting values for a single 2121 // header. 2122 // 2123 // The solution to this is to provide explicit methods to set or get headers. 2124 // This also has the benefit of allowing us to introduce additional variations, 2125 // including snake case, which we automatically convert to what Matthew King has 2126 // dubbed "corset case" - the hyphen-separated names with initial caps: 2127 // `Content-Type`. We use corset-case just in case we're dealing with servers 2128 // that haven't properly implemented the spec. 2129 2130 // Convert headers to corset-case. **Example:** `CONTENT-TYPE` will be converted 2131 // to `Content-Type`. 2132 2133 var corsetCase = function(string) { 2134 return string;//.toLowerCase() 2135 //.replace("_","-") 2136 // .replace(/(^|-)(\w)/g, 2137 // function(s) { return s.toUpperCase(); }); 2138 }; 2139 2140 // We suspect that `initializeHeaders` was once more complicated ... 2141 var initializeHeaders = function(object) { 2142 return {}; 2143 }; 2144 2145 // Access the `_headers` property using lazy initialization. **Warning:** If you 2146 // mix this into an object that is using the `_headers` property already, you're 2147 // going to have trouble. 2148 var $H = function(object) { 2149 return object._headers||(object._headers=initializeHeaders(object)); 2150 }; 2151 2152 // Hide the implementations as private functions, separate from how we expose them. 2153 2154 // The "real" `getHeader` function: get the header after normalizing the name. 2155 var getHeader = function(object,name) { 2156 return $H(object)[corsetCase(name)]; 2157 }; 2158 2159 // The "real" `getHeader` function: get one or more headers, or all of them 2160 // if you don't ask for any specifics. 2161 var getHeaders = function(object,names) { 2162 var keys = (names && names.length>0) ? names : Object.keys($H(object)); 2163 var hash = keys.reduce(function(hash,key) { 2164 hash[key] = getHeader(object,key); 2165 return hash; 2166 },{}); 2167 // Freeze the resulting hash so you don't mistakenly think you're modifying 2168 // the real headers. 2169 Object.freeze(hash); 2170 return hash; 2171 }; 2172 2173 // The "real" `setHeader` function: set a header, after normalizing the name. 2174 var setHeader = function(object,name,value) { 2175 $H(object)[corsetCase(name)] = value; 2176 return object; 2177 }; 2178 2179 // The "real" `setHeaders` function: set multiple headers based on a hash. 2180 var setHeaders = function(object,hash) { 2181 for( var key in hash ) { setHeader(object,key,hash[key]); }; 2182 return this; 2183 }; 2184 2185 // Here's where we actually bind the functionality to an object. These mixins work by 2186 // exposing mixin functions. Each function mixes in a specific batch of features. 2187 module.exports = { 2188 2189 // Add getters. 2190 getters: function(constructor) { 2191 constructor.prototype.getHeader = function(name) { return getHeader(this,name); }; 2192 constructor.prototype.getHeaders = function() { return getHeaders(this,arguments); }; 2193 }, 2194 // Add setters but as "private" methods. 2195 privateSetters: function(constructor) { 2196 constructor.prototype._setHeader = function(key,value) { return setHeader(this,key,value); }; 2197 constructor.prototype._setHeaders = function(hash) { return setHeaders(this,hash); }; 2198 }, 2199 // Add setters. 2200 setters: function(constructor) { 2201 constructor.prototype.setHeader = function(key,value) { return setHeader(this,key,value); }; 2202 constructor.prototype.setHeaders = function(hash) { return setHeaders(this,hash); }; 2203 }, 2204 // Add both getters and setters. 2205 gettersAndSetters: function(constructor) { 2206 constructor.prototype.getHeader = function(name) { return getHeader(this,name); }; 2207 constructor.prototype.getHeaders = function() { return getHeaders(this,arguments); }; 2208 constructor.prototype.setHeader = function(key,value) { return setHeader(this,key,value); }; 2209 constructor.prototype.setHeaders = function(hash) { return setHeaders(this,hash); }; 2210 } 2211 }; 2212 2213 }); 2214 2215 require.define("/node_modules/iconv-lite/package.json", function (require, module, exports, __dirname, __filename) { 2216 module.exports = {} 2217 }); 2218 2219 require.define("/node_modules/iconv-lite/index.js", function (require, module, exports, __dirname, __filename) { 2220 // Module exports 2221 var iconv = module.exports = { 2222 toEncoding: function(str, encoding) { 2223 return iconv.getCodec(encoding).toEncoding(str); 2224 }, 2225 fromEncoding: function(buf, encoding) { 2226 return iconv.getCodec(encoding).fromEncoding(buf); 2227 }, 2228 2229 defaultCharUnicode: '�', 2230 defaultCharSingleByte: '?', 2231 2232 // Get correct codec for given encoding. 2233 getCodec: function(encoding) { 2234 var enc = encoding || "utf8"; 2235 var codecOptions = undefined; 2236 while (1) { 2237 if (getType(enc) === "String") 2238 enc = enc.replace(/[- ]/g, "").toLowerCase(); 2239 var codec = iconv.encodings[enc]; 2240 var type = getType(codec); 2241 if (type === "String") { 2242 // Link to other encoding. 2243 codecOptions = {originalEncoding: enc}; 2244 enc = codec; 2245 } 2246 else if (type === "Object" && codec.type != undefined) { 2247 // Options for other encoding. 2248 codecOptions = codec; 2249 enc = codec.type; 2250 } 2251 else if (type === "Function") 2252 // Codec itself. 2253 return codec(codecOptions); 2254 else 2255 throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')"); 2256 } 2257 }, 2258 2259 // Define basic encodings 2260 encodings: { 2261 internal: function(options) { 2262 return { 2263 toEncoding: function(str) { 2264 return new Buffer(ensureString(str), options.originalEncoding); 2265 }, 2266 fromEncoding: function(buf) { 2267 return ensureBuffer(buf).toString(options.originalEncoding); 2268 } 2269 }; 2270 }, 2271 utf8: "internal", 2272 ucs2: "internal", 2273 binary: "internal", 2274 ascii: "internal", 2275 base64: "internal", 2276 2277 // Codepage single-byte encodings. 2278 singlebyte: function(options) { 2279 // Prepare chars if needed 2280 if (!options.chars || (options.chars.length !== 128 && options.chars.length !== 256)) 2281 throw new Error("Encoding '"+options.type+"' has incorrect 'chars' (must be of len 128 or 256)"); 2282 2283 if (options.chars.length === 128) 2284 options.chars = asciiString + options.chars; 2285 2286 if (!options.charsBuf) { 2287 options.charsBuf = new Buffer(options.chars, 'ucs2'); 2288 } 2289 2290 if (!options.revCharsBuf) { 2291 options.revCharsBuf = new Buffer(65536); 2292 var defChar = iconv.defaultCharSingleByte.charCodeAt(0); 2293 for (var i = 0; i < options.revCharsBuf.length; i++) 2294 options.revCharsBuf[i] = defChar; 2295 for (var i = 0; i < options.chars.length; i++) 2296 options.revCharsBuf[options.chars.charCodeAt(i)] = i; 2297 } 2298 2299 return { 2300 toEncoding: function(str) { 2301 str = ensureString(str); 2302 2303 var buf = new Buffer(str.length); 2304 var revCharsBuf = options.revCharsBuf; 2305 for (var i = 0; i < str.length; i++) 2306 buf[i] = revCharsBuf[str.charCodeAt(i)]; 2307 2308 return buf; 2309 }, 2310 fromEncoding: function(buf) { 2311 buf = ensureBuffer(buf); 2312 2313 // Strings are immutable in JS -> we use ucs2 buffer to speed up computations. 2314 var charsBuf = options.charsBuf; 2315 var newBuf = new Buffer(buf.length*2); 2316 var idx1 = 0, idx2 = 0; 2317 for (var i = 0, _len = buf.length; i < _len; i++) { 2318 idx1 = buf[i]*2; idx2 = i*2; 2319 newBuf[idx2] = charsBuf[idx1]; 2320 newBuf[idx2+1] = charsBuf[idx1+1]; 2321 } 2322 return newBuf.toString('ucs2'); 2323 } 2324 }; 2325 }, 2326 2327 // Codepage double-byte encodings. 2328 table: function(options) { 2329 var table = options.table, key, revCharsTable = options.revCharsTable; 2330 if (!table) { 2331 throw new Error("Encoding '" + options.type +"' has incorect 'table' option"); 2332 } 2333 if(!revCharsTable) { 2334 revCharsTable = options.revCharsTable = {}; 2335 for (key in table) { 2336 revCharsTable[table[key]] = parseInt(key); 2337 } 2338 } 2339 2340 return { 2341 toEncoding: function(str) { 2342 str = ensureString(str); 2343 var strLen = str.length; 2344 var bufLen = strLen; 2345 for (var i = 0; i < strLen; i++) 2346 if (str.charCodeAt(i) >> 7) 2347 bufLen++; 2348 2349 var newBuf = new Buffer(bufLen), gbkcode, unicode, 2350 defaultChar = revCharsTable[iconv.defaultCharUnicode.charCodeAt(0)]; 2351 2352 for (var i = 0, j = 0; i < strLen; i++) { 2353 unicode = str.charCodeAt(i); 2354 if (unicode >> 7) { 2355 gbkcode = revCharsTable[unicode] || defaultChar; 2356 newBuf[j++] = gbkcode >> 8; //high byte; 2357 newBuf[j++] = gbkcode & 0xFF; //low byte 2358 } else {//ascii 2359 newBuf[j++] = unicode; 2360 } 2361 } 2362 return newBuf; 2363 }, 2364 fromEncoding: function(buf) { 2365 buf = ensureBuffer(buf); 2366 var bufLen = buf.length, strLen = 0; 2367 for (var i = 0; i < bufLen; i++) { 2368 strLen++; 2369 if (buf[i] & 0x80) //the high bit is 1, so this byte is gbkcode's high byte.skip next byte 2370 i++; 2371 } 2372 var newBuf = new Buffer(strLen*2), unicode, gbkcode, 2373 defaultChar = iconv.defaultCharUnicode.charCodeAt(0); 2374 2375 for (var i = 0, j = 0; i < bufLen; i++, j+=2) { 2376 gbkcode = buf[i]; 2377 if (gbkcode & 0x80) { 2378 gbkcode = (gbkcode << 8) + buf[++i]; 2379 unicode = table[gbkcode] || defaultChar; 2380 } else { 2381 unicode = gbkcode; 2382 } 2383 newBuf[j] = unicode & 0xFF; //low byte 2384 newBuf[j+1] = unicode >> 8; //high byte 2385 } 2386 return newBuf.toString('ucs2'); 2387 } 2388 } 2389 } 2390 } 2391 }; 2392 2393 // Add aliases to convert functions 2394 iconv.encode = iconv.toEncoding; 2395 iconv.decode = iconv.fromEncoding; 2396 2397 // Load other encodings from files in /encodings dir. 2398 var encodingsDir = __dirname+"/encodings/", 2399 fs = require('fs'); 2400 fs.readdirSync(encodingsDir).forEach(function(file) { 2401 if(fs.statSync(encodingsDir + file).isDirectory()) return; 2402 var encodings = require(encodingsDir + file) 2403 for (var key in encodings) 2404 iconv.encodings[key] = encodings[key] 2405 }); 2406 2407 // Utilities 2408 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'+ 2409 ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f'; 2410 2411 var ensureBuffer = function(buf) { 2412 buf = buf || new Buffer(0); 2413 return (buf instanceof Buffer) ? buf : new Buffer(buf.toString(), "utf8"); 2414 } 2415 2416 var ensureString = function(str) { 2417 str = str || ""; 2418 return (str instanceof String) ? str : str.toString((str instanceof Buffer) ? 'utf8' : undefined); 2419 } 2420 2421 var getType = function(obj) { 2422 return Object.prototype.toString.call(obj).slice(8, -1); 2423 } 2424 2425 2426 }); 2427 2428 require.define("/node_modules/http-browserify/package.json", function (require, module, exports, __dirname, __filename) { 2429 module.exports = {"main":"index.js","browserify":"browser.js"} 2430 }); 2431 2432 require.define("/node_modules/http-browserify/browser.js", function (require, module, exports, __dirname, __filename) { 2433 var http = module.exports; 2434 var EventEmitter = require('events').EventEmitter; 2435 var Request = require('./lib/request'); 2436 2437 http.request = function (params, cb) { 2438 if (!params) params = {}; 2439 if (!params.host) params.host = window.location.host.split(':')[0]; 2440 if (!params.port) params.port = window.location.port; 2441 2442 var req = new Request(new xhrHttp, params); 2443 if (cb) req.on('response', cb); 2444 return req; 2445 }; 2446 2447 http.get = function (params, cb) { 2448 params.method = 'GET'; 2449 var req = http.request(params, cb); 2450 req.end(); 2451 return req; 2452 }; 2453 2454 var xhrHttp = (function () { 2455 if (typeof window === 'undefined') { 2456 throw new Error('no window object present'); 2457 } 2458 else if (window.XMLHttpRequest) { 2459 return window.XMLHttpRequest; 2460 } 2461 else if (window.ActiveXObject) { 2462 var axs = [ 2463 'Msxml2.XMLHTTP.6.0', 2464 'Msxml2.XMLHTTP.3.0', 2465 'Microsoft.XMLHTTP' 2466 ]; 2467 for (var i = 0; i < axs.length; i++) { 2468 try { 2469 var ax = new(window.ActiveXObject)(axs[i]); 2470 return function () { 2471 if (ax) { 2472 var ax_ = ax; 2473 ax = null; 2474 return ax_; 2475 } 2476 else { 2477 return new(window.ActiveXObject)(axs[i]); 2478 } 2479 }; 2480 } 2481 catch (e) {} 2482 } 2483 throw new Error('ajax not supported in this browser') 2484 } 2485 else { 2486 throw new Error('ajax not supported in this browser'); 2487 } 2488 })(); 2489 2490 http.STATUS_CODES = { 2491 100 : 'Continue', 2492 101 : 'Switching Protocols', 2493 102 : 'Processing', // RFC 2518, obsoleted by RFC 4918 2494 200 : 'OK', 2495 201 : 'Created', 2496 202 : 'Accepted', 2497 203 : 'Non-Authoritative Information', 2498 204 : 'No Content', 2499 205 : 'Reset Content', 2500 206 : 'Partial Content', 2501 207 : 'Multi-Status', // RFC 4918 2502 300 : 'Multiple Choices', 2503 301 : 'Moved Permanently', 2504 302 : 'Moved Temporarily', 2505 303 : 'See Other', 2506 304 : 'Not Modified', 2507 305 : 'Use Proxy', 2508 307 : 'Temporary Redirect', 2509 400 : 'Bad Request', 2510 401 : 'Unauthorized', 2511 402 : 'Payment Required', 2512 403 : 'Forbidden', 2513 404 : 'Not Found', 2514 405 : 'Method Not Allowed', 2515 406 : 'Not Acceptable', 2516 407 : 'Proxy Authentication Required', 2517 408 : 'Request Time-out', 2518 409 : 'Conflict', 2519 410 : 'Gone', 2520 411 : 'Length Required', 2521 412 : 'Precondition Failed', 2522 413 : 'Request Entity Too Large', 2523 414 : 'Request-URI Too Large', 2524 415 : 'Unsupported Media Type', 2525 416 : 'Requested Range Not Satisfiable', 2526 417 : 'Expectation Failed', 2527 418 : 'I\'m a teapot', // RFC 2324 2528 422 : 'Unprocessable Entity', // RFC 4918 2529 423 : 'Locked', // RFC 4918 2530 424 : 'Failed Dependency', // RFC 4918 2531 425 : 'Unordered Collection', // RFC 4918 2532 426 : 'Upgrade Required', // RFC 2817 2533 500 : 'Internal Server Error', 2534 501 : 'Not Implemented', 2535 502 : 'Bad Gateway', 2536 503 : 'Service Unavailable', 2537 504 : 'Gateway Time-out', 2538 505 : 'HTTP Version not supported', 2539 506 : 'Variant Also Negotiates', // RFC 2295 2540 507 : 'Insufficient Storage', // RFC 4918 2541 509 : 'Bandwidth Limit Exceeded', 2542 510 : 'Not Extended' // RFC 2774 2543 }; 2544 2545 }); 2546 2547 require.define("/node_modules/http-browserify/lib/request.js", function (require, module, exports, __dirname, __filename) { 2548 var EventEmitter = require('events').EventEmitter; 2549 var Response = require('./response'); 2550 var isSafeHeader = require('./isSafeHeader'); 2551 2552 var Request = module.exports = function (xhr, params) { 2553 var self = this; 2554 self.xhr = xhr; 2555 self.body = ''; 2556 2557 var uri = params.host + ':' + params.port + (params.path || '/'); 2558 2559 xhr.open( 2560 params.method || 'GET', 2561 (params.scheme || 'http') + '://' + uri, 2562 true 2563 ); 2564 2565 if (params.headers) { 2566 Object.keys(params.headers).forEach(function (key) { 2567 if (!isSafeHeader(key)) return; 2568 var value = params.headers[key]; 2569 if (Array.isArray(value)) { 2570 value.forEach(function (v) { 2571 xhr.setRequestHeader(key, v); 2572 }); 2573 } 2574 else xhr.setRequestHeader(key, value) 2575 }); 2576 } 2577 2578 var res = new Response(xhr); 2579 res.on('ready', function () { 2580 self.emit('response', res); 2581 }); 2582 2583 xhr.onreadystatechange = function () { 2584 res.handle(xhr); 2585 }; 2586 }; 2587 2588 Request.prototype = new EventEmitter; 2589 2590 Request.prototype.setHeader = function (key, value) { 2591 if ((Array.isArray && Array.isArray(value)) 2592 || value instanceof Array) { 2593 for (var i = 0; i < value.length; i++) { 2594 this.xhr.setRequestHeader(key, value[i]); 2595 } 2596 } 2597 else { 2598 this.xhr.setRequestHeader(key, value); 2599 } 2600 }; 2601 2602 Request.prototype.write = function (s) { 2603 this.body += s; 2604 }; 2605 2606 Request.prototype.end = function (s) { 2607 if (s !== undefined) this.write(s); 2608 this.xhr.send(this.body); 2609 }; 2610 2611 }); 2612 2613 require.define("/node_modules/http-browserify/lib/response.js", function (require, module, exports, __dirname, __filename) { 2614 var EventEmitter = require('events').EventEmitter; 2615 var isSafeHeader = require('./isSafeHeader'); 2616 2617 var Response = module.exports = function (xhr) { 2618 this.xhr = xhr; 2619 this.offset = 0; 2620 }; 2621 2622 Response.prototype = new EventEmitter; 2623 2624 var capable = { 2625 streaming : true, 2626 status2 : true 2627 }; 2628 2629 function parseHeaders (xhr) { 2630 var lines = xhr.getAllResponseHeaders().split(/\r?\n/); 2631 var headers = {}; 2632 for (var i = 0; i < lines.length; i++) { 2633 var line = lines[i]; 2634 if (line === '') continue; 2635 2636 var m = line.match(/^([^:]+):\s*(.*)/); 2637 if (m) { 2638 var key = m[1].toLowerCase(), value = m[2]; 2639 2640 if (headers[key] !== undefined) { 2641 if ((Array.isArray && Array.isArray(headers[key])) 2642 || headers[key] instanceof Array) { 2643 headers[key].push(value); 2644 } 2645 else { 2646 headers[key] = [ headers[key], value ]; 2647 } 2648 } 2649 else { 2650 headers[key] = value; 2651 } 2652 } 2653 else { 2654 headers[line] = true; 2655 } 2656 } 2657 return headers; 2658 } 2659 2660 Response.prototype.getHeader = function (key) { 2661 var header = this.headers ? this.headers[key.toLowerCase()] : null; 2662 if (header) return header; 2663 2664 // Work around Mozilla bug #608735 [https://bugzil.la/608735], which causes 2665 // getAllResponseHeaders() to return {} if the response is a CORS request. 2666 // xhr.getHeader still works correctly. 2667 if (isSafeHeader(key)) { 2668 return this.xhr.getResponseHeader(key); 2669 } 2670 return null; 2671 }; 2672 2673 Response.prototype.handle = function () { 2674 var xhr = this.xhr; 2675 if (xhr.readyState === 2 && capable.status2) { 2676 try { 2677 this.statusCode = xhr.status; 2678 this.headers = parseHeaders(xhr); 2679 } 2680 catch (err) { 2681 capable.status2 = false; 2682 } 2683 2684 if (capable.status2) { 2685 this.emit('ready'); 2686 } 2687 } 2688 else if (capable.streaming && xhr.readyState === 3) { 2689 try { 2690 if (!this.statusCode) { 2691 this.statusCode = xhr.status; 2692 this.headers = parseHeaders(xhr); 2693 this.emit('ready'); 2694 } 2695 } 2696 catch (err) {} 2697 2698 try { 2699 this.write(); 2700 } 2701 catch (err) { 2702 capable.streaming = false; 2703 } 2704 } 2705 else if (xhr.readyState === 4) { 2706 if (!this.statusCode) { 2707 this.statusCode = xhr.status; 2708 this.emit('ready'); 2709 } 2710 this.write(); 2711 2712 if (xhr.error) { 2713 this.emit('error', xhr.responseText); 2714 } 2715 else this.emit('end'); 2716 } 2717 }; 2718 2719 Response.prototype.write = function () { 2720 var xhr = this.xhr; 2721 if (xhr.responseText.length > this.offset) { 2722 this.emit('data', xhr.responseText.slice(this.offset)); 2723 this.offset = xhr.responseText.length; 2724 } 2725 }; 2726 2727 }); 2728 2729 require.define("/node_modules/http-browserify/lib/isSafeHeader.js", function (require, module, exports, __dirname, __filename) { 2730 // Taken from http://dxr.mozilla.org/mozilla/mozilla-central/content/base/src/nsXMLHttpRequest.cpp.html 2731 var unsafeHeaders = [ 2732 "accept-charset", 2733 "accept-encoding", 2734 "access-control-request-headers", 2735 "access-control-request-method", 2736 "connection", 2737 "content-length", 2738 "cookie", 2739 "cookie2", 2740 "content-transfer-encoding", 2741 "date", 2742 "expect", 2743 "host", 2744 "keep-alive", 2745 "origin", 2746 "referer", 2747 "set-cookie", 2748 "te", 2749 "trailer", 2750 "transfer-encoding", 2751 "upgrade", 2752 "user-agent", 2753 "via" 2754 ]; 2755 2756 module.exports = function (headerName) { 2757 if (!headerName) return false; 2758 return (unsafeHeaders.indexOf(headerName.toLowerCase()) === -1) 2759 }; 2760 2761 }); 2762 2763 require.alias("http-browserify", "/node_modules/http"); 2764 2765 require.alias("http-browserify", "/node_modules/https");