pipeline.js.map 19.6 KB
{"version":3,"sources":["pipeline.js"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,IAAM,CAAC,GAAiB,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC1C,IAAM,MAAM,GAAY,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC1C,IAAM,QAAQ,GAAU,OAAO,CAAC,UAAU,CAAC,CAAC;AAC5C,IAAM,KAAK,GAAa,OAAO,CAAC,SAAS,CAAC,CAAC;AAC3C,IAAM,IAAI,GAAc,OAAO,CAAC,IAAI,CAAC,CAAC;;eACd,OAAO,CAAC,SAAS,CAAC;;IAAlC,OAAO,YAAP,OAAO;;gBACS,OAAO,CAAC,MAAM,CAAC;;IAA/B,OAAO,aAAP,OAAO;;AACf,IAAM,IAAI,GAAc,OAAO,CAAC,MAAM,CAAC,CAAC;AACxC,IAAM,OAAO,GAAW,OAAO,CAAC,SAAS,CAAC,CAAC;AAC3C,IAAM,cAAc,GAAI,OAAO,CAAC,yCAAyC,CAAC,CAAC;AAC3E,IAAM,GAAG,GAAe,OAAO,CAAC,KAAK,CAAC,CAAC;AACvC,IAAM,KAAK,GAAa,OAAO,CAAC,uBAAuB,CAAC,CAAC;;;;;IAKnD,QAAQ;YAAR,QAAQ;;AAED,WAFP,QAAQ,CAEA,OAAO,EAAE;0BAFjB,QAAQ;;AAGV,+BAHE,QAAQ,6CAGF;AACR,QAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;;;;;;AACxB,wCAAoB,QAAQ,CAAC,QAAQ;YAA5B,OAAO;;AACd,YAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;OAAA;;;;;;;;;;;;;;;GACtB;;;;;eAPG,QAAQ;;WASN,gBAAC,KAAK,EAAE,IAAI,EAAE;AAClB,UAAM,OAAO,GAAK,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACjD,UAAM,OAAO,GAAK,IAAI,CAAC,QAAQ,CAAC;AAChC,aAAO,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;;AAEjC,aAAO,IAAI,CACR,YAAY,CAAC,OAAO,CAAC,CACrB,IAAI,CAAC,UAAS,QAAQ,EAAE;AACvB,gBAAQ,CAAC,IAAI,GAAO,IAAI,CAAC,GAAG,EAAE,CAAC;AAC/B,gBAAQ,CAAC,OAAO,GAAI,OAAO,CAAC;AAC5B,eAAO,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC5C,eAAO,QAAQ,CAAC;OACjB,CAAC,SACI,CAAC,UAAS,KAAK,EAAE;AACrB,eAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AAC9C,cAAM,IAAI,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;OACpC,CAAC,CAAC;KACN;;;WAEW,sBAAC,OAAO,EAAE;;;AACpB,aAAO,IAAI,CACR,oBAAoB,CAAC,OAAO,CAAC,CAC7B,IAAI,CAAC,UAAC,QAAQ,EAAI;AACjB,eAAO,MAAK,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;OACjD,CAAC,CAAC;KACN;;;WAEmB,8BAAC,OAAO,EAAE;AAC5B,UAAM,OAAO,GAAW,IAAI,CAAC,QAAQ,CAAC;AACtC,UAAM,eAAe,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;;AAEnF,aAAO,QAAQ,CAAC,MAAM,CAAC,eAAe,EAAE,UAAS,YAAY,EAAE,cAAc,EAAE;AAC3E,eAAO,YAAY,IAAI,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;OACzD,EAAE,IAAI,CAAC,CACP,IAAI,CAAC,UAAS,QAAQ,EAAE;AACvB,cAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE,wCAAwC,CAAC,CAAC;AACpG,eAAO,QAAQ,CAAC;OACjB,CAAC,CAAC;KACN;;;WAEe,0BAAC,OAAO,EAAE,gBAAgB,EAAE;AAC1C,UAAM,OAAO,GAAa,IAAI,CAAC,QAAQ,CAAC;AACxC,UAAM,gBAAgB,GAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;;AAErD,aAAO,QAAQ,CAAC,MAAM,CAAC,gBAAgB,EAAE,UAAS,YAAY,EAAE,eAAe,EAAE;AAC7E,eAAO,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;OACxD,EAAE,gBAAgB,CAAC,CACnB,IAAI,CAAC,UAAS,QAAQ,EAAE;AACvB,cAAM,CAAC,QAAQ,IAAI,QAAQ,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE,yCAAyC,CAAC,CAAC;AACrG,eAAO,QAAQ,CAAC;OACjB,CAAC,CAAC;KACN;;;;;;;;WAOS,oBAAC,OAAO,EAAE;AAClB,YAAM,CAAC,OAAO,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC;AACnD,YAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,6EAA6E,CAAC,CAAC;AACpI,UAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;KACpB;;;;;WAGY,uBAAC,OAAO,EAAE;AACrB,YAAM,CAAC,OAAO,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC;AACnD,UAAI,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAClC,UAAI,KAAK,GAAG,CAAC,CAAC,EAAE;AACd,YAAI,CAAC,MAAM,CAAC,KAAK,EAAC,CAAC,CAAC,CAAC;OACtB;KACF;;;;;;;;WAoBiB,8BAAG;;AAEnB,UAAM,MAAM,GAAG,EAAE,CAAC;AAClB,WAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;AAClC,YAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EACtB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;OAAA,AACzB,OAAO,MAAM,CAAC;KACf;;;;;WAGkB,+BAAG;;AAEpB,UAAM,MAAM,GAAG,EAAE,CAAC;AAClB,WAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;AAClC,YAAI,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EACtB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;OAAA,AACzB,OAAO,MAAM,CAAC;KACf;;;;;;;;;;WAjCgB,oBAAC,OAAO,EAAE;AACzB,YAAM,CAAC,OAAO,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC;AACnD,YAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,8EAA8E,CAAC,CAAC;AACrI,UAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;KAC7B;;;;;WAGmB,uBAAC,OAAO,EAAE;AAC5B,YAAM,CAAC,OAAO,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC;AACnD,UAAI,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAC3C,UAAI,KAAK,GAAG,CAAC,CAAC,EAAE;AACd,YAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAC,CAAC,CAAC,CAAC;OAC/B;KACF;;;WA6BkB,sBAAC,OAAO,EAAE,OAAO,EAAE;AACpC,UAAI,OAAO,CAAC,QAAQ;;;AAGlB,eAAO,CAAC,GAAG,GAAG,cAAc,CAAC,kBAAkB,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,KAE/E,OAAO,CAAC,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,IAAI,kBAAkB,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;KACpF;;;;;;;;;;WASkB,sBAAC,OAAO,EAAE,OAAO,EAAE;AACpC,UAAI,OAAO,CAAC,OAAO,EACjB,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,UAAC,KAAK,EAAE,IAAI,EAAI;AACtC,eAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;OACrD,CAAC,CAAC;AACL,UAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EACpC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;;;;uBAGtC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;;UAA/B,IAAI,cAAJ,IAAI;;AACZ,aAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;;;AAGlC,UAAM,YAAY,GAAG,EAAE,IAAI,EAAJ,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAC9D,aAAO,CAAC,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;UACnC,QAAQ,GAAe,YAAY,CAAnC,QAAQ;UAAE,QAAQ,GAAK,YAAY,CAAzB,QAAQ;;AAC1B,UAAI,QAAQ,IAAI,QAAQ,EAAE;AACxB,eAAO,CAAC,GAAG,wBAAsB,QAAQ,SAAI,QAAQ,CAAG,CAAC;AACzD,YAAM,MAAM,GAAG,IAAI,MAAM,CAAI,QAAQ,SAAI,QAAQ,CAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACxE,eAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,aAAY,MAAM,CAAG,CAAC;OAC1D;KACF;;;;;;;;WAOqB,yBAAC,OAAO,EAAE,OAAO,EAAE;UAC/B,GAAG,GAAK,OAAO,CAAf,GAAG;;wBAC8B,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;;UAA/C,QAAQ,eAAR,QAAQ;UAAE,QAAQ,eAAR,QAAQ;UAAE,QAAQ,eAAR,QAAQ;;AAEpC,UAAI,QAAQ,KAAK,OAAO,EAAE;;;;;AAKxB,YAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAC1B,OAAO,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,EAAH,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;;AAEtD,YAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;AACrD,YAAM,MAAM,GAAK,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;AAC3C,YAAI,MAAM,EAAE;AACV,cAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;AAC/C,iBAAO,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,GAAG,EAAH,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;SACzD,MACC,OAAO,IAAI,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,EAAH,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;OAEvD;;;UAGO,OAAO,GAAO,OAAO,CAArB,OAAO;;AACf,UAAM,YAAY,GAAI,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC5D,UAAI,YAAY,EACd,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;;AAEjD,UAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,IAAI,SAAQ,OAAO,CAAC,IAAI,CAAC,CAAC;AACpG,aAAO,WAAW,CACf,IAAI,CAAC,UAAS,IAAI,EAAE;;AAEnB,YAAM,WAAW,GAAG,IAAI,OAAO,CAAC;AAC9B,gBAAM,EAAU,OAAO,CAAC,MAAM;AAC9B,aAAG,EAAa,OAAO,CAAC,GAAG;AAC3B,iBAAO,EAAS,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE;AAC1C,eAAK,EAAW,OAAO,CAAC,KAAK;AAC7B,cAAI,EAAJ,IAAI;AACJ,aAAG,EAAa,KAAK;AACrB,wBAAc,EAAE,KAAK;AACrB,mBAAS,EAAO,OAAO,CAAC,SAAS;AACjC,sBAAY,EAAI,OAAO,CAAC,YAAY,IAAI,CAAC;SAC1C,CAAC,CAAC;;AAEH,eAAO,aAAY,UAAS,OAAO,EAAE,MAAM,EAAE;AAC3C,qBAAW,CACR,EAAE,CAAC,UAAU,EAAE,UAAC,QAAQ,EAAI;;;;AAI3B,gBAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAI;AACzE,kBAAI,OAAO,CAAC,KAAK,CAAC;;;;;;AAChB,qDAAiB,KAAK;wBAAb,IAAI;;AACX,2BAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;mBAAA;;;;;;;;;;;;;;;qBAE7B,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;AAC9B,qBAAO,OAAO,CAAC;aAChB,EAAE,EAAE,CAAC,CAAC;;AAEP,mBAAO,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE;AACnC,iBAAG,EAAS,OAAO,CAAC,GAAG;AACvB,oBAAM,EAAM,QAAQ,CAAC,UAAU;AAC/B,qBAAO,EAAK,IAAI,OAAO,CAAC,cAAc,CAAC;aACxC,CAAC,CAAC,CAAC;WACL,CAAC,CACD,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;SACxB,CAAC,CAAC;OAEJ,CAAC,CAAC;KACN;;;;;;WAKmB,uBAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;AAC/C,cAAQ,CAAC,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACjD,aAAO,QAAQ,CAAC;KACjB;;;WAEmB,uBAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;;;wBAEhB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;;UAA7C,QAAQ,eAAR,QAAQ;UAAE,QAAQ,eAAR,QAAQ;;AAC1B,UAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;AACzD,aAAO,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACvD,aAAO,QAAQ,CAAC;KACjB;;;WAEoB,wBAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE;UACxC,MAAM,GAAM,QAAQ,CAApB,MAAM;;AACd,UAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE;AAC1F,YAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAC9B,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;;AAEhC,YAAM,SAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAClD,YAAI,SAAQ,KAAK,IAAI,EACnB,OAAO,QAAQ,CAAC;;AAElB,YAAI,OAAO,CAAC,cAAc,IAAI,EAAE,EAC9B,OAAO,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;;AAEhC,eAAO,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAQ,CAAC,CAAC;AACtD,UAAE,OAAO,CAAC,cAAc,CAAC;AACzB,YAAI,MAAM,KAAK,GAAG,EAAE;AAClB,iBAAO,CAAC,MAAM,GAAG,KAAK,CAAC;AACvB,iBAAO,CAAC,OAAO,UAAO,CAAC,cAAc,CAAC,CAAC;AACvC,iBAAO,CAAC,OAAO,UAAO,CAAC,gBAAgB,CAAC,CAAC;AACzC,iBAAO,CAAC,OAAO,UAAO,CAAC,2BAA2B,CAAC,CAAC;SACrD;;;AAGD,eAAO,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;AAC5C,eAAO,CAAC,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,SAAQ,CAAC,CAAC;AACvD,eAAO,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;OAC/C,MACC,OAAO,QAAQ,CAAC;KACnB;;;SA7RG,QAAQ;GAAS,KAAK;;AAoS5B,QAAQ,CAAC,QAAQ,GAAG,CAClB,QAAQ,CAAC,YAAY,EACrB,QAAQ,CAAC,YAAY,EACrB,QAAQ,CAAC,aAAa,EACtB,QAAQ,CAAC,aAAa,EACtB,QAAQ,CAAC,cAAc,CACxB,CAAC;;AAEF,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC","file":"pipeline.js","sourcesContent":["const _               = require('lodash');\nconst assert          = require('assert');\nconst Bluebird        = require('bluebird');\nconst Fetch           = require('./fetch');\nconst File            = require('fs');\nconst { Headers }     = require('./fetch');\nconst { isArray }     = require('util');\nconst Path            = require('path');\nconst Request         = require('request');\nconst resourceLoader  = require('jsdom/lib/jsdom/browser/resource-loader');\nconst URL             = require('url');\nconst Utils           = require('jsdom/lib/jsdom/utils');\n\n\n// Pipeline is sequence of request/response handlers that are used to prepare a\n// request, make the request, and process the response.\nclass Pipeline extends Array {\n\n  constructor(browser) {\n    super();\n    this._browser = browser;\n    for (let handler of Pipeline._default)\n      this.push(handler);\n  }\n\n  _fetch(input, init) {\n    const request   = new Fetch.Request(input, init);\n    const browser   = this._browser;\n    browser.emit('request', request);\n\n    return this\n      ._runPipeline(request)\n      .then(function(response) {\n        response.time     = Date.now();\n        response.request  = request;\n        browser.emit('response', request, response);\n        return response;\n      })\n      .catch(function(error) {\n        browser._debug('Resource error', error.stack);\n        throw new TypeError(error.message);\n      });\n  }\n\n  _runPipeline(request) {\n    return this\n      ._getOriginalResponse(request)\n      .then((response)=> {\n        return this._prepareResponse(request, response);\n      });\n  }\n\n  _getOriginalResponse(request) {\n    const browser         = this._browser;\n    const requestHandlers = this.getRequestHandlers().concat(Pipeline.makeHTTPRequest);\n\n    return Bluebird.reduce(requestHandlers, function(lastResponse, requestHandler) {\n        return lastResponse || requestHandler(browser, request);\n      }, null)\n      .then(function(response) {\n        assert(response && response.hasOwnProperty('statusText'), 'Request handler must return a response');\n        return response;\n      });\n  }\n\n  _prepareResponse(request, originalResponse) {\n    const browser           = this._browser;\n    const responseHandlers  = this.getResponseHandlers();\n\n    return Bluebird.reduce(responseHandlers, function(lastResponse, responseHandler) {\n        return responseHandler(browser, request, lastResponse);\n      }, originalResponse)\n      .then(function(response) {\n        assert(response && response.hasOwnProperty('statusText'), 'Response handler must return a response');\n        return response;\n      });\n  }\n\n\n  // -- Handlers --\n\n  // Add a request or response handler.  This handler will only be used by this\n  // pipeline instance (browser).\n  addHandler(handler) {\n    assert(handler.call, 'Handler must be a function');\n    assert(handler.length === 2 || handler.length === 3, 'Handler function takes 2 (request handler) or 3 (reponse handler) arguments');\n    this.push(handler);\n  }\n\n  // Remove a request or response handler.\n  removeHandler(handler) {\n    assert(handler.call, 'Handler must be a function');\n    var index = this.indexOf(handler);\n    if (index > -1) {\n      this.splice(index,1);\n    }\n  }\n\n  // Add a request or response handler.  This handler will be used by any new\n  // pipeline instance (browser).\n  static addHandler(handler) {\n    assert(handler.call, 'Handler must be a function');\n    assert(handler.length === 2 || handler.length === 3, 'Handler function takes 2 (request handler) or 3 (response handler) arguments');\n    this._default.push(handler);\n  }\n  \n  // Remove a request or response handler.\n  static removeHandler(handler) {\n    assert(handler.call, 'Handler must be a function');\n    var index = this._default.indexOf(handler);\n    if (index > -1) {\n      this._default.splice(index,1);\n    }\n  }\n\n  // Get array of request handlers\n  getRequestHandlers() {\n    // N.B. inheriting from an Array is slightly broken, so just iterate manually\n    const result = [];\n    for (let i = 0; i < this.length; i++)\n      if (this[i].length === 2)\n        result.push(this[i]);\n    return result;\n  }\n\n  // Get array of request handlers\n  getResponseHandlers() {\n    // N.B. inheriting from an Array is slightly broken, so just iterate manually\n    const result = [];\n    for (let i = 0; i < this.length; i++)\n      if (this[i].length === 3)\n        result.push(this[i]);\n    return result;\n  }\n\n\n  // -- Prepare request --\n\n  // This handler normalizes the request URL.\n  //\n  // It turns relative URLs into absolute URLs based on the current document URL\n  // or base element, or if no document open, based on browser.site property.\n  static normalizeURL(browser, request) {\n    if (browser.document)\n    // Resolve URL relative to document URL/base, or for new browser, using\n    // Browser.site\n      request.url = resourceLoader.resolveResourceUrl(browser.document, request.url);\n    else\n      request.url = Utils.resolveHref(browser.site || 'http://localhost', request.url);\n  }\n\n\n  // This handler mergers request headers.\n  //\n  // It combines headers provided in the request with custom headers defined by\n  // the browser (user agent, authentication, etc).\n  //\n  // It also normalizes all headers by down-casing the header names.\n  static mergeHeaders(browser, request) {\n    if (browser.headers)\n      _.each(browser.headers, (value, name)=> {\n        request.headers.append(name, browser.headers[name]);\n      });\n    if (!request.headers.has('User-Agent'))\n      request.headers.set('User-Agent', browser.userAgent);\n\n    // Always pass Host: from request URL\n    const { host } = URL.parse(request.url);\n    request.headers.set('Host', host);\n\n    // HTTP Basic authentication\n    const authenticate = { host, username: null, password: null };\n    browser.emit('authenticate', authenticate);\n    const { username, password } = authenticate;\n    if (username && password) {\n      browser.log(`Authenticating as ${username}:${password}`);\n      const base64 = new Buffer(`${username}:${password}`).toString('base64');\n      request.headers.set('authorization',  `Basic ${base64}`);\n    }\n  }\n\n\n  // -- Retrieve actual resource --\n\n  // Used to perform HTTP request (also supports file: resources).  This is always\n  // the last request handler.\n  static makeHTTPRequest(browser, request) {\n    const { url } = request;\n    const { protocol, hostname, pathname } = URL.parse(url);\n\n    if (protocol === 'file:') {\n\n      // If the request is for a file:// descriptor, just open directly from the\n      // file system rather than getting node's http (which handles file://\n      // poorly) involved.\n      if (request.method !== 'GET')\n        return new Fetch.Response('', { url, status: 405 });\n\n      const filename = Path.normalize(decodeURI(pathname));\n      const exists   = File.existsSync(filename);\n      if (exists) {\n        const stream = File.createReadStream(filename);\n        return new Fetch.Response(stream, { url, status: 200 });\n      } else\n        return new Fetch.Response('', { url, status: 404 });\n\n    }\n\n    // We're going to use cookies later when receiving response.\n    const { cookies }   = browser;\n    const cookieHeader  = cookies.serialize(hostname, pathname);\n    if (cookieHeader)\n      request.headers.append('Cookie', cookieHeader);\n\n    const consumeBody = /^POST|PUT/.test(request.method) && request._consume() || Promise.resolve(null);\n    return consumeBody\n      .then(function(body) {\n\n        const httpRequest = new Request({\n          method:         request.method,\n          uri:            request.url,\n          headers:        request.headers.toObject(),\n          proxy:          browser.proxy,\n          body,\n          jar:            false,\n          followRedirect: false,\n          strictSSL:      browser.strictSSL,\n          localAddress:   browser.localAddress || 0\n        });\n\n        return new Promise(function(resolve, reject) {\n          httpRequest\n            .on('response', (response)=> {\n              // Request returns an object where property name is header name,\n              // property value is either header value, or an array if header sent\n              // multiple times (e.g. `Set-Cookie`).\n              const arrayOfHeaders = _.reduce(response.headers, (headers, value, name)=> {\n                if (isArray(value))\n                  for (let item of value)\n                    headers.push([name, item]);\n                else\n                  headers.push([name, value]);\n                return headers;\n              }, []);\n\n              resolve(new Fetch.Response(response, {\n                url:        request.url,\n                status:     response.statusCode,\n                headers:    new Headers(arrayOfHeaders)\n              }));\n            })\n            .on('error', reject);\n        });\n\n      });\n  }\n\n\n  // -- Handle response --\n\n  static handleHeaders(browser, request, response) {\n    response.headers = new Headers(response.headers);\n    return response;\n  }\n\n  static handleCookies(browser, request, response) {\n    // Set cookies from response: call update() with array of headers\n    const { hostname, pathname } = URL.parse(request.url);\n    const newCookies = response.headers.getAll('Set-Cookie');\n    browser.cookies.update(newCookies, hostname, pathname);\n    return response;\n  }\n\n  static handleRedirect(browser, request, response) {\n    const { status }  = response;\n    if (status === 301 || status === 302 || status === 303 || status === 307 || status === 308) {\n      if (request.redirect === 'error')\n        return Fetch.Response.error();\n\n      const location = response.headers.get('Location');\n      if (location === null)\n        return response;\n\n      if (request._redirectCount >= 20)\n        return Fetch.Response.error();\n\n      browser.emit('redirect', request, response, location);\n      ++request._redirectCount;\n      if (status !== 307) {\n        request.method = 'GET';\n        request.headers.delete('Content-Type');\n        request.headers.delete('Content-Length');\n        request.headers.delete('Content-Transfer-Encoding');\n      }\n\n      // This request is referer for next\n      request.headers.set('Referer', request.url);\n      request.url = Utils.resolveHref(request.url, location);\n      return browser.pipeline._runPipeline(request);\n    } else\n      return response;\n  }\n\n}\n\n\n// The default pipeline.  All new pipelines are instantiated with this set of\n// handlers.\nPipeline._default = [\n  Pipeline.normalizeURL,\n  Pipeline.mergeHeaders,\n  Pipeline.handleHeaders,\n  Pipeline.handleCookies,\n  Pipeline.handleRedirect\n];\n\nmodule.exports = Pipeline;\n\n"]}