114. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 10/2/2017 1:40:10 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.

114.1 Files compared

# Location File Last Modified
1 chef-repo.zip\chef-repo\project_cookbooks\mocks\files\default\node-mocks\nodeMockServices-1.3.0.52.zip\node_modules\request request.js Mon Jul 7 18:21:00 2014 UTC
2 chef-repo.zip\chef-repo\project_cookbooks\mocks\files\default\node-mocks\nodeMockServices-1.3.0.52.zip\node_modules\request request.js Mon Oct 2 18:01:31 2017 UTC

114.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 2 2796
Changed 1 4
Inserted 0 0
Removed 0 0

114.3 Comparison options

Whitespace
Character case Differences in character case are significant
Line endings Differences in line endings (CR and LF characters) are ignored
CR/LF characters Not shown in the comparison detail

114.4 Active regular expressions

No regular expressions were active.

114.5 Comparison detail

  1   var option al = requi re('./lib/ optional')
  2     , http =  require(' http')
  3     , https  = optional ('https')
  4     , tls =  optional(' tls')
  5     , url =  require('u rl')
  6     , util =  require(' util')
  7     , stream  = require ('stream')
  8     , qs = r equire('qs ')
  9     , querys tring = re quire('que rystring')
  10     , crypto  = require ('crypto')
  11     , zlib =  require(' zlib')
  12  
  13     , oauth  = optional ('oauth-si gn')
  14     , hawk =  optional( 'hawk')
  15     , aws =  optional(' aws-sign2' )
  16     , httpSi gnature =  optional(' http-signa ture')
  17     , uuid =  require(' node-uuid' )
  18     , mime =  require(' mime-types ')
  19     , tunnel  = optiona l('tunnel- agent')
  20     , _safeS tringify =  require(' json-strin gify-safe' )
  21  
  22     , Foreve rAgent = r equire('fo rever-agen t')
  23     , FormDa ta = optio nal('form- data')
  24  
  25     , cookie s = requir e('./lib/c ookies')
  26     , global CookieJar  = cookies. jar()
  27  
  28     , copy =  require(' ./lib/copy ')
  29     , debug  = require( './lib/deb ug')
  30     , getSaf e = requir e('./lib/g etSafe')
  31     , net =  require('n et')
  32     ;
  33  
  34   function s afeStringi fy (obj) {
  35     var ret
  36     try { re t = JSON.s tringify(o bj) }
  37     catch (e ) { ret =  _safeStrin gify(obj)  }
  38     return r et
  39   }
  40  
  41   var global Pool = {}
  42   var isUrl  = /^https? :|^unix:/
  43  
  44  
  45   // Hacky f ix for pre -0.4.4 htt ps
  46   if (https  && !https. Agent) {
  47     https.Ag ent = func tion (opti ons) {
  48       http.A gent.call( this, opti ons)
  49     }
  50     util.inh erits(http s.Agent, h ttp.Agent)
  51     https.Ag ent.protot ype._getCo nnection =  function  (host, por t, cb) {
  52       var s  = tls.conn ect(port,  host, this .options,  function ( ) {
  53         // d o other ch ecks here?
  54         if ( cb) cb()
  55       })
  56       return  s
  57     }
  58   }
  59  
  60   function i sReadStrea m (rs) {
  61     return r s.readable  && rs.pat h && rs.mo de;
  62   }
  63  
  64   function t oBase64 (s tr) {
  65     return ( new Buffer (str || "" , "ascii") ).toString ("base64")
  66   }
  67  
  68   function m d5 (str) {
  69     return c rypto.crea teHash('md 5').update (str).dige st('hex')
  70   }
  71  
  72   function R equest (op tions) {
  73     stream.S tream.call (this)
  74     this.rea dable = tr ue
  75     this.wri table = tr ue
  76  
  77     if (type of options  === 'stri ng') {
  78       option s = {uri:o ptions}
  79     }
  80  
  81     var rese rved = Obj ect.keys(R equest.pro totype)
  82     for (var  i in opti ons) {
  83       if (re served.ind exOf(i) == = -1) {
  84         this [i] = opti ons[i]
  85       } else  {
  86         if ( typeof opt ions[i] == = 'functio n') {
  87           de lete optio ns[i]
  88         }
  89       }
  90     }
  91  
  92     if (opti ons.method ) {
  93       this.e xplicitMet hod = true
  94     }
  95  
  96     this.can Tunnel = o ptions.tun nel !== fa lse && tun nel;
  97  
  98     this.ini t(options)
  99   }
  100   util.inher its(Reques t, stream. Stream)
  101   Request.pr ototype.in it = funct ion (optio ns) {
  102     // init( ) contains  all the c ode to set up the req uest objec t.
  103     // the a ctual outg oing reque st is not  started un til start( ) is calle d
  104     // this  function i s called f rom both t he constru ctor and o n redirect .
  105     var self  = this
  106     if (!opt ions) opti ons = {}
  107  
  108     if (!sel f.method)  self.metho d = option s.method | | 'GET'
  109     self.loc alAddress  = options. localAddre ss
  110  
  111     debug(op tions)
  112     if (!sel f.pool &&  self.pool  !== false)  self.pool  = globalP ool
  113     self.des ts = self. dests || [ ]
  114     self.__i sRequestRe quest = tr ue
  115  
  116     // Prote ct against  double ca llback
  117     if (!sel f._callbac k && self. callback)  {
  118       self._ callback =  self.call back
  119       self.c allback =  function ( ) {
  120         if ( self._call backCalled ) return / / Print a  warning ma ybe?
  121         self ._callback Called = t rue
  122         self ._callback .apply(sel f, argumen ts)
  123       }
  124       self.o n('error',  self.call back.bind( ))
  125       self.o n('complet e', self.c allback.bi nd(self, n ull))
  126     }
  127  
  128     if (self .url && !s elf.uri) {
  129       // Peo ple use th is propert y instead  all the ti me so why  not just s upport it.
  130       self.u ri = self. url
  131       delete  self.url
  132     }
  133  
  134     if (!sel f.uri) {
  135       // thi s will thr ow if unha ndled but  is handlea ble when i n a redire ct
  136       return  self.emit ('error',  new Error( "options.u ri is a re quired arg ument"))
  137     } else {
  138       if (ty peof self. uri == "st ring") sel f.uri = ur l.parse(se lf.uri)
  139     }
  140  
  141     if (self .strictSSL  === false ) {
  142       self.r ejectUnaut horized =  false
  143     }
  144  
  145     if (self .proxy) {
  146       if (ty peof self. proxy == ' string') s elf.proxy  = url.pars e(self.pro xy)
  147  
  148       // do  the HTTP C ONNECT dan ce using k oichik/nod e-tunnel
  149       if (ht tp.globalA gent && se lf.uri.pro tocol ===  "https:" & & self.can Tunnel) {
  150         var  tunnelFn =  self.prox y.protocol  === "http :"
  151                       ?  tunnel.ht tpsOverHtt p : tunnel .httpsOver Https
  152  
  153         var  tunnelOpti ons = { pr oxy: { hos t: self.pr oxy.hostna me
  154                                         , por t: +self.p roxy.port
  155                                         , pro xyAuth: se lf.proxy.a uth
  156                                         , hea ders: { Ho st: self.u ri.hostnam e + ':' +
  157                                               (self.uri. port || se lf.uri.pro tocol ===  'https:' ?  443 : 80)  }}
  158                               , re jectUnauth orized: se lf.rejectU nauthorize d
  159                               , ca : this.ca  }
  160  
  161         self .agent = t unnelFn(tu nnelOption s)
  162         self .tunnel =  true
  163       }
  164     }
  165  
  166     if (!sel f.uri.path name) {sel f.uri.path name = '/' }
  167  
  168     if (!sel f.uri.host  && !self. protocol== 'unix:') {
  169       // Inv alid URI:  it may gen erate lot  of bad err ors, like  "TypeError : Cannot c all method  'indexOf'  of undefi ned" in Co okieJar
  170       // Det ect and re ject it as  soon as p ossible
  171       var fa ultyUri =  url.format (self.uri)
  172       var me ssage = 'I nvalid URI  "' + faul tyUri + '" '
  173       if (Ob ject.keys( options).l ength ===  0) {
  174         // N o option ?  This can  be the sig n of a red irect
  175         // A s this is  a case whe re the use r cannot d o anything  (they did n't call r equest dir ectly with  this URL)
  176         // t hey should  be warned  that it c an be caus ed by a re direction  (can save  some hair)
  177         mess age += '.  This can b e caused b y a crappy  redirecti on.'
  178       }
  179       self.e mit('error ', new Err or(message ))
  180       return  // This e rror was f atal
  181     }
  182  
  183     self._re directsFol lowed = se lf._redire ctsFollowe d || 0
  184     self.max Redirects  = (self.ma xRedirects  !== undef ined) ? se lf.maxRedi rects : 10
  185     self.fol lowRedirec t = (self. followRedi rect !== u ndefined)  ? self.fol lowRedirec t : true
  186     self.fol lowAllRedi rects = (s elf.follow AllRedirec ts !== und efined) ?  self.follo wAllRedire cts : fals e
  187     if (self .followRed irect || s elf.follow AllRedirec ts)
  188       self.r edirects =  self.redi rects || [ ]
  189  
  190     self.hea ders = sel f.headers  ? copy(sel f.headers)  : {}
  191  
  192     self.set Host = fal se
  193     if (!sel f.hasHeade r('host'))  {
  194       self.s etHeader(' host', sel f.uri.host name)
  195       if (se lf.uri.por t) {
  196         if (  !(self.ur i.port ===  80 && sel f.uri.prot ocol === ' http:') &&
  197               !(self.ur i.port ===  443 && se lf.uri.pro tocol ===  'https:')  )
  198         self .setHeader ('host', s elf.getHea der('host' ) + (':'+s elf.uri.po rt) )
  199       }
  200       self.s etHost = t rue
  201     }
  202  
  203     self.jar (self._jar  || option s.jar)
  204  
  205     if (!sel f.uri.port ) {
  206         if (self.u ri.protoco l == 'http :') {self. uri.port =   PORT }
  207         else if (s elf.uri.pr otocol ==  'https:')  {self.uri. port =  PORT }
  208     }
  209  
  210     if (self .proxy &&  !self.tunn el) {
  211       self.p ort = self .proxy.por t
  212       self.h ost = self .proxy.hos tname
  213     } else {
  214       self.p ort = self .uri.port
  215       self.h ost = self .uri.hostn ame
  216     }
  217  
  218     self.cli entErrorHa ndler = fu nction (er ror) {
  219       if (se lf._aborte d) return
  220       if (se lf.req &&  self.req._ reusedSock et && erro r.code ===  'ECONNRES ET'
  221           &&  self.agen t.addReque stNoreuse)  {
  222         self .agent = {  addReques t: self.ag ent.addReq uestNoreus e.bind(sel f.agent) }
  223         self .start()
  224         self .req.end()
  225         retu rn
  226       }
  227       if (se lf.timeout  && self.t imeoutTime r) {
  228         clea rTimeout(s elf.timeou tTimer)
  229         self .timeoutTi mer = null
  230       }
  231       self.e mit('error ', error)
  232     }
  233  
  234     self._pa rserErrorH andler = f unction (e rror) {
  235       if (th is.res) {
  236         if ( this.res.r equest) {
  237           th is.res.req uest.emit( 'error', e rror)
  238         } el se {
  239           th is.res.emi t('error',  error)
  240         }
  241       } else  {
  242         this ._httpMess age.emit(' error', er ror)
  243       }
  244     }
  245  
  246     self._bu ildRequest  = functio n(){
  247       var se lf = this;
  248  
  249       if (op tions.form ) {
  250         self .form(opti ons.form)
  251       }
  252  
  253       if (op tions.qs)  self.qs(op tions.qs)
  254  
  255       if (se lf.uri.pat h) {
  256         self .path = se lf.uri.pat h
  257       } else  {
  258         self .path = se lf.uri.pat hname + (s elf.uri.se arch || "" )
  259       }
  260  
  261       if (se lf.path.le ngth === 0 ) self.pat h = '/'
  262  
  263  
  264       // Aut h must hap pen last i n case sig ning is de pendent on  other hea ders
  265       if (op tions.oaut h) {
  266         self .oauth(opt ions.oauth )
  267       }
  268  
  269       if (op tions.aws)  {
  270         self .aws(optio ns.aws)
  271       }
  272  
  273       if (op tions.hawk ) {
  274         self .hawk(opti ons.hawk)
  275       }
  276  
  277       if (op tions.http Signature)  {
  278         self .httpSigna ture(optio ns.httpSig nature)
  279       }
  280  
  281       if (op tions.auth ) {
  282         if ( Object.pro totype.has OwnPropert y.call(opt ions.auth,  'username ')) option s.auth.use r = option s.auth.use rname
  283         if ( Object.pro totype.has OwnPropert y.call(opt ions.auth,  'password ')) option s.auth.pas s = option s.auth.pas sword
  284  
  285         self .auth(
  286           op tions.auth .user,
  287           op tions.auth .pass,
  288           op tions.auth .sendImmed iately,
  289           op tions.auth .bearer
  290         )
  291       }
  292  
  293       if (se lf.gzip &&  !self.has Header('ac cept-encod ing')) {
  294         self .setHeader ('accept-e ncoding',  'gzip')
  295       }
  296  
  297       if (se lf.uri.aut h && !self .hasHeader ('authoriz ation')) {
  298         var  authPieces  = self.ur i.auth.spl it(':').ma p(function (item){ re turn query string.une scape(item ) })
  299         self .auth(auth Pieces[0],  authPiece s.slice(1) .join(':') , true)
  300       }
  301       if (se lf.proxy & & self.pro xy.auth &&  !self.has Header('pr oxy-author ization')  && !self.t unnel) {
  302         self .setHeader ('proxy-au thorizatio n', "Basic  " + toBas e64(self.p roxy.auth. split(':') .map(funct ion(item){  return qu erystring. unescape(i tem)}).joi n(':')))
  303       }
  304  
  305  
  306       if (se lf.proxy & & !self.tu nnel) self .path = (s elf.uri.pr otocol + ' //' + self .uri.host  + self.pat h)
  307  
  308       if (op tions.json ) {
  309         self .json(opti ons.json)
  310       } else  if (optio ns.multipa rt) {
  311         self .boundary  = uuid()
  312         self .multipart (options.m ultipart)
  313       }
  314  
  315       if (se lf.body) {
  316         var  length = 0
  317         if ( !Buffer.is Buffer(sel f.body)) {
  318           if  (Array.is Array(self .body)) {
  319              for (var i  = 0; i <  self.body. length; i+ +) {
  320                length + = self.bod y[i].lengt h
  321              }
  322           }  else {
  323              self.body  = new Buff er(self.bo dy)
  324              length = s elf.body.l ength
  325           }
  326         } el se {
  327           le ngth = sel f.body.len gth
  328         }
  329         if ( length) {
  330           if  (!self.ha sHeader('c ontent-len gth')) sel f.setHeade r('content -length',  length)
  331         } el se {
  332           th row new Er ror('Argum ent error,  options.b ody.')
  333         }
  334       }
  335  
  336       var pr otocol = s elf.proxy  && !self.t unnel ? se lf.proxy.p rotocol :  self.uri.p rotocol
  337         , de faultModul es = {'htt p:':http,  'https:':h ttps, 'uni x:':http}
  338         , ht tpModules  = self.htt pModules | | {}
  339         ;
  340       self.h ttpModule  = httpModu les[protoc ol] || def aultModule s[protocol ]
  341  
  342       if (!s elf.httpMo dule) retu rn this.em it('error' , new Erro r("Invalid  protocol:  " + proto col))
  343  
  344       if (op tions.ca)  self.ca =  options.ca
  345  
  346       if (!s elf.agent)  {
  347         if ( options.ag entOptions ) self.age ntOptions  = options. agentOptio ns
  348  
  349         if ( options.ag entClass)  {
  350           se lf.agentCl ass = opti ons.agentC lass
  351         } el se if (opt ions.forev er) {
  352           se lf.agentCl ass = prot ocol === ' http:' ? F oreverAgen t : Foreve rAgent.SSL
  353         } el se {
  354           se lf.agentCl ass = self .httpModul e.Agent
  355         }
  356       }
  357  
  358       if (se lf.pool == = false) {
  359         self .agent = f alse
  360       } else  {
  361         self .agent = s elf.agent  || self.ge tAgent()
  362         if ( self.maxSo ckets) {
  363           //  Don't use  our pooli ng if node  has the r efactored  client
  364           se lf.agent.m axSockets  = self.max Sockets
  365         }
  366         if ( self.pool. maxSockets ) {
  367           //  Don't use  our pooli ng if node  has the r efactored  client
  368           se lf.agent.m axSockets  = self.poo l.maxSocke ts
  369         }
  370       }
  371  
  372       self.o n('pipe',  function ( src) {
  373         if ( self.ntick  && self._ started) t hrow new E rror("You  cannot pip e to this  stream aft er the out bound requ est has st arted.")
  374         self .src = src
  375         if ( isReadStre am(src)) {
  376           if  (!self.ha sHeader('c ontent-typ e')) self. setHeader( 'content-t ype', mime .lookup(sr c.path))
  377         } el se {
  378           if  (src.head ers) {
  379              for (var i  in src.he aders) {
  380                if (!sel f.hasHeade r(i)) {
  381                  self.s etHeader(i , src.head ers[i])
  382                }
  383              }
  384           }
  385           if  (self._js on && !sel f.hasHeade r('content -type'))
  386              self.setHe ader('cont ent-type',  'applicat ion/json')
  387           if  (src.meth od && !sel f.explicit Method) {
  388              self.metho d = src.me thod
  389           }
  390         }
  391  
  392         // s elf.on('pi pe', funct ion () {
  393         //    console.e rror("You  have alrea dy piped t o this str eam. Pipei ng twice i s likely t o break th e request. ")
  394         // } )
  395       })
  396  
  397       proces s.nextTick (function  () {
  398         if ( self._abor ted) retur n
  399  
  400         if ( self._form ) {
  401           se lf.setHead ers(self._ form.getHe aders())
  402           tr y {
  403              var length  = self._f orm.getLen gthSync()
  404              if (!self. hasHeader( 'content-l ength')) s elf.setHea der('conte nt-length' , length)
  405           }  catch(e){}
  406           se lf._form.p ipe(self)
  407         }
  408         if ( self.body)  {
  409           if  (Array.is Array(self .body)) {
  410              self.body. forEach(fu nction (pa rt) {
  411                self.wri te(part)
  412              })
  413           }  else {
  414              self.write (self.body )
  415           }
  416           se lf.end()
  417         } el se if (sel f.requestB odyStream)  {
  418           co nsole.warn ("options. requestBod yStream is  deprecate d, please  pass the r equest obj ect to str eam.pipe." )
  419           se lf.request BodyStream .pipe(self )
  420         } el se if (!se lf.src) {
  421           if  (self.met hod !== 'G ET' && typ eof self.m ethod !==  'undefined ') {
  422              self.setHe ader('cont ent-length ', 0)
  423           }
  424           se lf.end()
  425         }
  426         self .ntick = t rue
  427       })
  428  
  429     } // End  _buildReq uest
  430  
  431     self._ha ndleUnixSo cketURI =  function(s elf){
  432       // Par se URI and  extract a  socket pa th (tested  as a vali d socket u sing net.c onnect), a nd a http  style path  suffix
  433       // Thu s http req uests can  be made to  a socket  using the  uri unix:/ /tmp/my.so cket/urlpa th
  434       // and  a request  for '/url path' will  be sent t o the unix  socket at  /tmp/my.s ocket
  435  
  436       self.u nixsocket  = true;
  437  
  438       var fu ll_path =  self.uri.h ref.replac e(self.uri .protocol+ '/', '');
  439  
  440       var lo okup = ful l_path.spl it('/');
  441       var er ror_connec ting = tru e;
  442  
  443       var lo okup_table  = {};
  444       do { l ookup_tabl e[lookup.j oin('/')]= {} } while (lookup.po p())
  445       for (r  in lookup _table){
  446         try_ next(r);
  447       }
  448  
  449       functi on try_nex t(table_ro w){
  450         var  client = n et.connect ( table_ro w );
  451         clie nt.path =  table_row
  452         clie nt.on('err or', funct ion(){ loo kup_table[ this.path] .error_con necting=tr ue; this.e nd(); });
  453         clie nt.on('con nect', fun ction(){ l ookup_tabl e[this.pat h].error_c onnecting= false; thi s.end(); } );
  454         tabl e_row.clie nt = clien t;
  455       }
  456  
  457       wait_f or_socket_ response() ;
  458  
  459       respon se_counter  = 0;
  460  
  461       functi on wait_fo r_socket_r esponse(){
  462         var  detach;
  463         if(' undefined'  == typeof  setImmedi ate ) deta ch = proce ss.nextTic k
  464         else  detach =  setImmedia te;
  465         deta ch(functio n(){
  466           //  counter t o prevent  infinite b locking wa iting for  an open so cket to be  found.
  467           re sponse_cou nter++;
  468           va r trying =  false;
  469           fo r (r in lo okup_table ){
  470              //console. log(r, loo kup_table[ r], lookup _table[r]. error_conn ecting)
  471              if('undefi ned' == ty peof looku p_table[r] .error_con necting)
  472                trying =  true;
  473           }
  474           if (trying &&  response_ counter<10 00)
  475              wait_for_s ocket_resp onse()
  476           el se
  477              set_socket _propertie s();
  478         })
  479       }
  480  
  481       functi on set_soc ket_proper ties(){
  482         var  host;
  483         for  (r in look up_table){
  484           if (lookup_ta ble[r].err or_connect ing === fa lse){
  485              host = r
  486           }
  487         }
  488         if(! host){
  489           se lf.emit('e rror', new  Error("Fa iled to co nnect to a ny socket  in "+full_ path))
  490         }
  491         var  path = ful l_path.rep lace(host,  '')
  492  
  493         self .socketPat h = host
  494         self .uri.pathn ame = path
  495         self .uri.href  = path
  496         self .uri.path  = path
  497         self .host = ''
  498         self .hostname  = ''
  499         dele te self.ho st
  500         dele te self.ho stname
  501         self ._buildReq uest();
  502       }
  503     }
  504  
  505     // Inter cept UNIX  protocol r equests to  change pr operties t o match so cket
  506     if(/^uni x:/.test(s elf.uri.pr otocol)){
  507       self._ handleUnix SocketURI( self);
  508     } else {
  509       self._ buildReque st();
  510     }
  511  
  512   }
  513  
  514   // Must ca ll this wh en followi ng a redir ect from h ttps to ht tp or vice  versa
  515   // Attempt s to keep  everything  as identi cal as pos sible, but  update th e
  516   // httpMod ule, Tunne ling agent , and/or F orever Age nt in use.
  517   Request.pr ototype._u pdateProto col = func tion () {
  518     var self  = this
  519     var prot ocol = sel f.uri.prot ocol
  520  
  521     if (prot ocol === ' https:') {
  522       // pre viously wa s doing ht tp, now do ing https
  523       // if  it's https , then we  might need  to tunnel  now.
  524       if (se lf.proxy & & self.can Tunnel) {
  525         self .tunnel =  true
  526         var  tunnelFn =  self.prox y.protocol  === 'http :'
  527                       ?  tunnel.ht tpsOverHtt p : tunnel .httpsOver Https
  528         var  tunnelOpti ons = { pr oxy: { hos t: self.pr oxy.hostna me
  529                                         , por t: +self.p roxy.port
  530                                         , pro xyAuth: se lf.proxy.a uth }
  531                               , re jectUnauth orized: se lf.rejectU nauthorize d
  532                               , ca : self.ca  }
  533         self .agent = t unnelFn(tu nnelOption s)
  534         retu rn
  535       }
  536  
  537       self.h ttpModule  = https
  538       switch  (self.age ntClass) {
  539         case  ForeverAg ent:
  540           se lf.agentCl ass = Fore verAgent.S SL
  541           br eak
  542         case  http.Agen t:
  543           se lf.agentCl ass = http s.Agent
  544           br eak
  545         defa ult:
  546           //  nothing w e can do.   Just hope  for the b est.
  547           re turn
  548       }
  549  
  550       // if  there's an  agent, we  need to g et a new o ne.
  551       if (se lf.agent)  self.agent  = self.ge tAgent()
  552  
  553     } else {
  554       // pre viously wa s doing ht tps, now d oing http
  555       // sto p any tunn eling.
  556       if (se lf.tunnel)  self.tunn el = false
  557       self.h ttpModule  = http
  558       switch  (self.age ntClass) {
  559         case  ForeverAg ent.SSL:
  560           se lf.agentCl ass = Fore verAgent
  561           br eak
  562         case  https.Age nt:
  563           se lf.agentCl ass = http .Agent
  564           br eak
  565         defa ult:
  566           //  nothing w e can do.   just hope  for the b est
  567           re turn
  568       }
  569  
  570       // if  there's an  agent, th en get a n ew one.
  571       if (se lf.agent)  {
  572         self .agent = n ull
  573         self .agent = s elf.getAge nt()
  574       }
  575     }
  576   }
  577  
  578   Request.pr ototype.ge tAgent = f unction ()  {
  579     var Agen t = this.a gentClass
  580     var opti ons = {}
  581     if (this .agentOpti ons) {
  582       for (v ar i in th is.agentOp tions) {
  583         opti ons[i] = t his.agentO ptions[i]
  584       }
  585     }
  586     if (this .ca) optio ns.ca = th is.ca
  587     if (this .ciphers)  options.ci phers = th is.ciphers
  588     if (this .securePro tocol) opt ions.secur eProtocol  = this.sec ureProtoco l
  589     if (this .secureOpt ions) opti ons.secure Options =  this.secur eOptions
  590     if (type of this.re jectUnauth orized !==  'undefine d') option s.rejectUn authorized  = this.re jectUnauth orized
  591  
  592     if (this .cert && t his.key) {
  593       option s.key = th is.key
  594       option s.cert = t his.cert
  595     }
  596  
  597     var pool Key = ''
  598  
  599     // diffe rent types  of agents  are in di fferent po ols
  600     if (Agen t !== this .httpModul e.Agent) {
  601       poolKe y += Agent .name
  602     }
  603  
  604     if (!thi s.httpModu le.globalA gent) {
  605       // nod e 0.4.x
  606       option s.host = t his.host
  607       option s.port = t his.port
  608       if (po olKey) poo lKey += ': '
  609       poolKe y += this. host + ':'  + this.po rt
  610     }
  611  
  612     // ca op tion is on ly relevan t if proxy  or destin ation are  https
  613     var prox y = this.p roxy
  614     if (type of proxy = == 'string ') proxy =  url.parse (proxy)
  615     var isHt tps = (pro xy && prox y.protocol  === 'http s:') || th is.uri.pro tocol ===  'https:'
  616     if (isHt tps) {
  617       if (op tions.ca)  {
  618         if ( poolKey) p oolKey +=  ':'
  619         pool Key += opt ions.ca
  620       }
  621  
  622       if (ty peof optio ns.rejectU nauthorize d !== 'und efined') {
  623         if ( poolKey) p oolKey +=  ':'
  624         pool Key += opt ions.rejec tUnauthori zed
  625       }
  626  
  627       if (op tions.cert )
  628         pool Key += opt ions.cert. toString(' ascii') +  options.ke y.toString ('ascii')
  629  
  630       if (op tions.ciph ers) {
  631         if ( poolKey) p oolKey +=  ':'
  632         pool Key += opt ions.ciphe rs
  633       }
  634  
  635       if (op tions.secu reProtocol ) {
  636         if ( poolKey) p oolKey +=  ':'
  637         pool Key += opt ions.secur eProtocol
  638       }
  639  
  640       if (op tions.secu reOptions)  {
  641         if ( poolKey) p oolKey +=  ':'
  642         pool Key += opt ions.secur eOptions
  643       }
  644     }
  645  
  646     if (this .pool ===  globalPool  && !poolK ey && Obje ct.keys(op tions).len gth === 0  && this.ht tpModule.g lobalAgent ) {
  647       // not  doing any thing spec ial.  Use  the global Agent
  648       return  this.http Module.glo balAgent
  649     }
  650  
  651     // we're  using a s tored agen t.  Make s ure it's p rotocol-sp ecific
  652     poolKey  = this.uri .protocol  + poolKey
  653  
  654     // alrea dy generat ed an agen t for this  setting
  655     if (this .pool[pool Key]) retu rn this.po ol[poolKey ]
  656  
  657     return t his.pool[p oolKey] =  new Agent( options)
  658   }
  659  
  660   Request.pr ototype.st art = func tion () {
  661     // start () is call ed once we  are ready  to send t he outgoin g HTTP req uest.
  662     // this  is usually  called on  the first  write(),  end() or o n nextTick ()
  663     var self  = this
  664  
  665     if (self ._aborted)  return
  666  
  667     self._st arted = tr ue
  668     self.met hod = self .method ||  'GET'
  669     self.hre f = self.u ri.href
  670  
  671     if (self .src && se lf.src.sta t && self. src.stat.s ize && !se lf.hasHead er('conten t-length') ) {
  672       self.s etHeader(' content-le ngth', sel f.src.stat .size)
  673     }
  674     if (self ._aws) {
  675       self.a ws(self._a ws, true)
  676     }
  677  
  678     // We ha ve a metho d named au th, which  is complet ely differ ent from t he http.re quest
  679     // auth  option.  I f we don't  remove it , we're go nna have a  bad time.
  680     var reqO ptions = c opy(self)
  681     delete r eqOptions. auth
  682  
  683     debug('m ake reques t', self.u ri.href)
  684     self.req  = self.ht tpModule.r equest(req Options, s elf.onResp onse.bind( self))
  685  
  686     if (self .timeout & & !self.ti meoutTimer ) {
  687       self.t imeoutTime r = setTim eout(funct ion () {
  688         self .req.abort ()
  689         var  e = new Er ror("ETIME DOUT")
  690         e.co de = "ETIM EDOUT"
  691         self .emit("err or", e)
  692       }, sel f.timeout)
  693  
  694       // Set  additiona l timeout  on socket  - in case  if remote
  695       // ser ver freeze  after sen ding heade rs
  696       if (se lf.req.set Timeout) {  // only w orks on no de 0.6+
  697         self .req.setTi meout(self .timeout,  function ( ) {
  698           if  (self.req ) {
  699              self.req.a bort()
  700              var e = ne w Error("E SOCKETTIME DOUT")
  701              e.code = " ESOCKETTIM EDOUT"
  702              self.emit( "error", e )
  703           }
  704         })
  705       }
  706     }
  707  
  708     self.req .on('error ', self.cl ientErrorH andler)
  709     self.req .on('drain ', functio n() {
  710       self.e mit('drain ')
  711     })
  712     self.on( 'end', fun ction() {
  713       if ( s elf.req.co nnection )  self.req. connection .removeLis tener('err or', self. _parserErr orHandler)
  714     })
  715     self.emi t('request ', self.re q)
  716   }
  717   Request.pr ototype.on Response =  function  (response)  {
  718     var self  = this
  719     debug('o nResponse' , self.uri .href, res ponse.stat usCode, re sponse.hea ders)
  720     response .on('end',  function( ) {
  721       debug( 'response  end', self .uri.href,  response. statusCode , response .headers)
  722     });
  723  
  724     // The c heck on re sponse.con nection is  a workaro und for br owserify.
  725     if (resp onse.conne ction && r esponse.co nnection.l isteners(' error').in dexOf(self ._parserEr rorHandler ) === -1)  {
  726       respon se.connect ion.setMax Listeners( 0)
  727       respon se.connect ion.once(' error', se lf._parser ErrorHandl er)
  728     }
  729     if (self ._aborted)  {
  730       debug( 'aborted',  self.uri. href)
  731       respon se.resume( )
  732       return
  733     }
  734     if (self ._paused)  response.p ause()
  735     // Check  that resp onse.resum e is defin ed. Workar ound for b rowserify.
  736     else res ponse.resu me && resp onse.resum e()
  737  
  738     self.res ponse = re sponse
  739     response .request =  self
  740     response .toJSON =  toJSON
  741  
  742     // XXX T his is dif ferent on  0.10, beca use SSL is  strict by  default
  743     if (self .httpModul e === http s &&
  744         self .strictSSL  &&
  745         !res ponse.clie nt.authori zed) {
  746       debug( 'strict ss l error',  self.uri.h ref)
  747       var ss lErr = res ponse.clie nt.authori zationErro r
  748       self.e mit('error ', new Err or('SSL Er ror: '+ ss lErr))
  749       return
  750     }
  751  
  752     if (self .setHost & & self.has Header('ho st')) dele te self.he aders[self .hasHeader ('host')]
  753     if (self .timeout & & self.tim eoutTimer)  {
  754       clearT imeout(sel f.timeoutT imer)
  755       self.t imeoutTime r = null
  756     }
  757  
  758     var targ etCookieJa r = (self. _jar && se lf._jar.se tCookie)?s elf._jar:g lobalCooki eJar;
  759     var addC ookie = fu nction (co okie) {
  760       //set  the cookie  if it's d omain in t he href's  domain.
  761       try {
  762         targ etCookieJa r.setCooki e(cookie,  self.uri.h ref, {igno reError: t rue});
  763       } catc h (e) {
  764         self .emit('err or', e);
  765       }
  766     }
  767  
  768     if (hasH eader('set -cookie',  response.h eaders) &&  (!self._d isableCook ies)) {
  769       var he aderName =  hasHeader ('set-cook ie', respo nse.header s)
  770       if (Ar ray.isArra y(response .headers[h eaderName] )) respons e.headers[ headerName ].forEach( addCookie)
  771       else a ddCookie(r esponse.he aders[head erName])
  772     }
  773  
  774     var redi rectTo = n ull
  775     if (resp onse.statu sCode >= 3 00 && resp onse.statu sCode < 40 0 && hasHe ader('loca tion', res ponse.head ers)) {
  776       var lo cation = r esponse.he aders[hasH eader('loc ation', re sponse.hea ders)]
  777       debug( 'redirect' , location )
  778  
  779       if (se lf.followA llRedirect s) {
  780         redi rectTo = l ocation
  781       } else  if (self. followRedi rect) {
  782         swit ch (self.m ethod) {
  783           ca se 'PATCH' :
  784           ca se 'PUT':
  785           ca se 'POST':
  786           ca se 'DELETE ':
  787              // Do not  follow red irects
  788              break
  789           de fault:
  790              redirectTo  = locatio n
  791              break
  792         }
  793       }
  794     } else i f (respons e.statusCo de == 401  && self._h asAuth &&  !self._sen tAuth) {
  795       var au thHeader =  response. headers[ha sHeader('w ww-authent icate', re sponse.hea ders)]
  796       var au thVerb = a uthHeader  && authHea der.split( ' ')[0].to LowerCase( )
  797       debug( 'reauth',  authVerb)
  798  
  799       switch  (authVerb ) {
  800         case  'basic':
  801           se lf.auth(se lf._user,  self._pass , true)
  802           re directTo =  self.uri
  803           br eak
  804  
  805         case  'bearer':
  806           se lf.auth(nu ll, null,  true, self ._bearer)
  807           re directTo =  self.uri
  808           br eak
  809  
  810         case  'digest':
  811           //  TODO: Mor e complete  implement ation of R FC 2617.
  812           //    - check  challenge .algorithm
  813           //    - suppo rt algorit hm="MD5-se ss"
  814           //    - handl e challeng e.domain
  815           //    - suppo rt qop="au th-int" on ly
  816           //    - handl e Authenti cation-Inf o (not nec essarily?)
  817           //    - check  challenge .stale (no t necessar ily?)
  818           //    - incre ase nc (no t necessar ily?)
  819           //  For refer ence:
  820           //  http://to ols.ietf.o rg/html/rf c2617#sect ion-3
  821           //  https://g ithub.com/ bagder/cur l/blob/mas ter/lib/ht tp_digest. c
  822  
  823           va r challeng e = {}
  824           va r re = /([ a-z0-9_-]+ )=(?:"([^" ]+)"|([a-z 0-9_-]+))/ gi
  825           fo r (;;) {
  826              var match  = re.exec( authHeader )
  827              if (!match ) break
  828              challenge[ match[1]]  = match[2]  || match[ 3];
  829           }
  830  
  831           va r ha1 = md 5(self._us er + ':' +  challenge .realm + ' :' + self. _pass)
  832           va r ha2 = md 5(self.met hod + ':'  + self.uri .path)
  833           va r qop = /( ^|,)\s*aut h\s*($|,)/ .test(chal lenge.qop)  && 'auth'
  834           va r nc = qop  && '00000 001'
  835           va r cnonce =  qop && uu id().repla ce(/-/g, ' ')
  836           va r digestRe sponse = q op ? md5(h a1 + ':' +  challenge .nonce + ' :' + nc +  ':' + cnon ce + ':' +  qop + ':'  + ha2) :  md5(ha1 +  ':' + chal lenge.nonc e + ':' +  ha2)
  837           va r authValu es = {
  838              username:  self._user ,
  839              realm: cha llenge.rea lm,
  840              nonce: cha llenge.non ce,
  841              uri: self. uri.path,
  842              qop: qop,
  843              response:  digestResp onse,
  844              nc: nc,
  845              cnonce: cn once,
  846              algorithm:  challenge .algorithm ,
  847              opaque: ch allenge.op aque
  848           }
  849  
  850           au thHeader =  []
  851           fo r (var k i n authValu es) {
  852              if (!authV alues[k])  {
  853                //ignore
  854              } else if  (k === 'qo p' || k == = 'nc' ||  k === 'alg orithm') {
  855                authHead er.push(k  + '=' + au thValues[k ])
  856              } else {
  857                authHead er.push(k  + '="' + a uthValues[ k] + '"')
  858              }
  859           }
  860           au thHeader =  'Digest '  + authHea der.join(' , ')
  861           se lf.setHead er('author ization',  authHeader )
  862           se lf._sentAu th = true
  863  
  864           re directTo =  self.uri
  865           br eak
  866       }
  867     }
  868  
  869     if (redi rectTo) {
  870       debug( 'redirect  to', redir ectTo)
  871  
  872       // ign ore any po tential re sponse bod y.  it can not possib ly be usef ul
  873       // to  us at this  point.
  874       if (se lf._paused ) response .resume()
  875  
  876       if (se lf._redire ctsFollowe d >= self. maxRedirec ts) {
  877         self .emit('err or', new E rror("Exce eded maxRe directs. P robably st uck in a r edirect lo op "+self. uri.href))
  878         retu rn
  879       }
  880       self._ redirectsF ollowed +=  1
  881  
  882       if (!i sUrl.test( redirectTo )) {
  883         redi rectTo = u rl.resolve (self.uri. href, redi rectTo)
  884       }
  885  
  886       var ur iPrev = se lf.uri
  887       self.u ri = url.p arse(redir ectTo)
  888  
  889       // han dle the ca se where w e change p rotocol fr om https t o http or  vice versa
  890       if (se lf.uri.pro tocol !==  uriPrev.pr otocol) {
  891         self ._updatePr otocol()
  892       }
  893  
  894       self.r edirects.p ush(
  895         { st atusCode :  response. statusCode
  896         , re directUri:  redirectT o
  897         }
  898       )
  899       if (se lf.followA llRedirect s && respo nse.status Code != 40 1 && respo nse.status Code != 30 7) self.me thod = 'GE T'
  900       // sel f.method =  'GET' //  Force all  redirects  to use GET  || commen ted out fi xes #215
  901       delete  self.src
  902       delete  self.req
  903       delete  self.agen t
  904       delete  self._sta rted
  905       if (re sponse.sta tusCode !=  401 && re sponse.sta tusCode !=  307) {
  906         // R emove para meters fro m the prev ious respo nse, unles s this is  the second  request
  907         // f or a serve r that req uires dige st authent ication.
  908         dele te self.bo dy
  909         dele te self._f orm
  910         if ( self.heade rs) {
  911           if  (self.has Header('ho st')) dele te self.he aders[self .hasHeader ('host')]
  912           if  (self.has Header('co ntent-type ')) delete  self.head ers[self.h asHeader(' content-ty pe')]
  913           if  (self.has Header('co ntent-leng th')) dele te self.he aders[self .hasHeader ('content- length')]
  914         }
  915       }
  916  
  917       self.e mit('redir ect');
  918  
  919       self.i nit()
  920       return  // Ignore  the rest  of the res ponse
  921     } else {
  922       self._ redirectsF ollowed =  self._redi rectsFollo wed || 0
  923       // Be  a good str eam and em it end whe n the resp onse is fi nished.
  924       // Hac k to emit  end on clo se because  of a core  bug that  never fire s end
  925       respon se.on('clo se', funct ion () {
  926         if ( !self._end ed) self.r esponse.em it('end')
  927       })
  928  
  929       var da taStream
  930       if (se lf.gzip) {
  931         var  contentEnc oding = re sponse.hea ders["cont ent-encodi ng"] || "i dentity"
  932         cont entEncodin g = conten tEncoding. trim().toL owerCase()
  933  
  934         if ( contentEnc oding ===  "gzip") {
  935           da taStream =  zlib.crea teGunzip()
  936           re sponse.pip e(dataStre am)
  937         } el se {
  938           //  Since pre vious vers ions didn' t check fo r Content- Encoding h eader,
  939           //  ignore an y invalid  values to  preserve b ackwards-c ompatibili ty
  940           if  (contentE ncoding != = "identit y") {
  941              debug("ign oring unre cognized C ontent-Enc oding " +  contentEnc oding)
  942           }
  943           da taStream =  response
  944         }
  945       } else  {
  946         data Stream = r esponse
  947       }
  948  
  949       if (se lf.encodin g) {
  950         if ( self.dests .length != = 0) {
  951           co nsole.erro r("Ignorin g encoding  parameter  as this s tream is b eing piped  to anothe r stream w hich makes  the encod ing option  invalid." )
  952         } el se {
  953           //  gz stream s don't ha ve setEnco ding in v0 .8
  954           if  (dataStre am.setEnco ding) data Stream.set Encoding(s elf.encodi ng)
  955         }
  956       }
  957  
  958       self.e mit('respo nse', resp onse)
  959  
  960       self.d ests.forEa ch(functio n (dest) {
  961         self .pipeDest( dest)
  962       })
  963  
  964       dataSt ream.on("d ata", func tion (chun k) {
  965         self ._destdata  = true
  966         self .emit("dat a", chunk)
  967       })
  968       dataSt ream.on("e nd", funct ion (chunk ) {
  969         self ._ended =  true
  970         self .emit("end ", chunk)
  971       })
  972       dataSt ream.on("c lose", fun ction () { self.emit( "close")})
  973  
  974       if (se lf.callbac k) {
  975         var  buffer = [ ]
  976         var  bodyLen =  0
  977         self .on("data" , function  (chunk) {
  978           bu ffer.push( chunk)
  979           bo dyLen += c hunk.lengt h
  980         })
  981         self .on("end",  function  () {
  982           de bug('end e vent', sel f.uri.href )
  983           if  (self._ab orted) {
  984              debug('abo rted', sel f.uri.href )
  985              return
  986           }
  987  
  988           if  (buffer.l ength && B uffer.isBu ffer(buffe r[0])) {
  989              debug('has  body', se lf.uri.hre f, bodyLen )
  990              var body =  new Buffe r(bodyLen)
  991              var i = 0
  992              buffer.for Each(funct ion (chunk ) {
  993                chunk.co py(body, i , 0, chunk .length)
  994                i += chu nk.length
  995              })
  996              if (self.e ncoding == = null) {
  997                response .body = bo dy
  998              } else {
  999                response .body = bo dy.toStrin g(self.enc oding)
  1000              }
  1001           }  else if (b uffer.leng th) {
  1002              // The UTF 8 BOM [0xE F,0xBB,0xB F] is conv erted to [ 0xFE,0xFF]  in the JS  UTC16/UCS 2 represen tation.
  1003              // Strip t his value  out when t he encodin g is set t o 'utf8',  as upstrea m consumer s won't ex pect it an d it break s JSON.par se().
  1004              if (self.e ncoding == = 'utf8' & & buffer[0 ].length >  0 && buff er[0][0] = == "\uFEFF ") {
  1005                buffer[0 ] = buffer [0].substr ing(1)
  1006              }
  1007              response.b ody = buff er.join('' )
  1008           }
  1009  
  1010           if  (self._js on) {
  1011              try {
  1012                response .body = JS ON.parse(r esponse.bo dy)
  1013              } catch (e ) {}
  1014           }
  1015           de bug('emitt ing comple te', self. uri.href)
  1016           if (response. body == un defined &&  !self._js on) {
  1017              response.b ody = "";
  1018           }
  1019           se lf.emit('c omplete',  response,  response.b ody)
  1020         })
  1021       }
  1022       //if n o callback
  1023       else{
  1024         self .on("end",  function  () {
  1025           if  (self._ab orted) {
  1026              debug('abo rted', sel f.uri.href )
  1027              return
  1028           }
  1029           se lf.emit('c omplete',  response);
  1030         });
  1031       }
  1032     }
  1033     debug('f inish init  function' , self.uri .href)
  1034   }
  1035  
  1036   Request.pr ototype.ab ort = func tion () {
  1037     this._ab orted = tr ue
  1038  
  1039     if (this .req) {
  1040       this.r eq.abort()
  1041     }
  1042     else if  (this.resp onse) {
  1043       this.r esponse.ab ort()
  1044     }
  1045  
  1046     this.emi t("abort")
  1047   }
  1048  
  1049   Request.pr ototype.pi peDest = f unction (d est) {
  1050     var resp onse = thi s.response
  1051     // Calle d after th e response  is receiv ed
  1052     if (dest .headers & & !dest.he adersSent)  {
  1053       if (ha sHeader('c ontent-typ e', respon se.headers )) {
  1054         var  ctname = h asHeader(' content-ty pe', respo nse.header s)
  1055         if ( dest.setHe ader) dest .setHeader (ctname, r esponse.he aders[ctna me])
  1056         else  dest.head ers[ctname ] = respon se.headers [ctname]
  1057       }
  1058  
  1059       if (ha sHeader('c ontent-len gth', resp onse.heade rs)) {
  1060         var  clname = h asHeader(' content-le ngth', res ponse.head ers)
  1061         if ( dest.setHe ader) dest .setHeader (clname, r esponse.he aders[clna me])
  1062         else  dest.head ers[clname ] = respon se.headers [clname]
  1063       }
  1064     }
  1065     if (dest .setHeader  && !dest. headersSen t) {
  1066       for (v ar i in re sponse.hea ders) {
  1067         // I f the resp onse conte nt is bein g decoded,  the Conte nt-Encodin g header
  1068         // o f the resp onse doesn 't represe nt the pip ed content , so don't  pass it.
  1069         if ( !this.gzip  || i !==  'content-e ncoding')  {
  1070           de st.setHead er(i, resp onse.heade rs[i])
  1071         }
  1072       }
  1073       dest.s tatusCode  = response .statusCod e
  1074     }
  1075     if (this .pipefilte r) this.pi pefilter(r esponse, d est)
  1076   }
  1077  
  1078   // Composa ble API
  1079   Request.pr ototype.se tHeader =  function ( name, valu e, clobber ) {
  1080     if (clob ber === un defined) c lobber = t rue
  1081     if (clob ber || !th is.hasHead er(name))  this.heade rs[name] =  value
  1082     else thi s.headers[ this.hasHe ader(name) ] += ',' +  value
  1083     return t his
  1084   }
  1085   Request.pr ototype.se tHeaders =  function  (headers)  {
  1086     for (var  i in head ers) {this .setHeader (i, header s[i])}
  1087     return t his
  1088   }
  1089   Request.pr ototype.ha sHeader =  function ( header, he aders) {
  1090     var head ers = Obje ct.keys(he aders || t his.header s)
  1091       , lhea ders = hea ders.map(f unction (h ) {return  h.toLowerC ase()})
  1092       ;
  1093     header =  header.to LowerCase( )
  1094     for (var  i=0;i<lhe aders.leng th;i++) {
  1095       if (lh eaders[i]  === header ) return h eaders[i]
  1096     }
  1097     return f alse
  1098   }
  1099  
  1100   var hasHea der = Requ est.protot ype.hasHea der
  1101  
  1102   Request.pr ototype.qs  = functio n (q, clob ber) {
  1103     var base
  1104     if (!clo bber && th is.uri.que ry) base =  qs.parse( this.uri.q uery)
  1105     else bas e = {}
  1106  
  1107     for (var  i in q) {
  1108       base[i ] = q[i]
  1109     }
  1110  
  1111     if (qs.s tringify(b ase) === ' '){
  1112       return  this
  1113     }
  1114  
  1115     this.uri  = url.par se(this.ur i.href.spl it('?')[0]  + '?' + q s.stringif y(base))
  1116     this.url  = this.ur i
  1117     this.pat h = this.u ri.path
  1118  
  1119     return t his
  1120   }
  1121   Request.pr ototype.fo rm = funct ion (form)  {
  1122     if (form ) {
  1123       this.s etHeader(' content-ty pe', 'appl ication/x- www-form-u rlencoded;  charset=u tf-8')
  1124       this.b ody = (typ eof form = == 'string ') ? form. toString(' utf8') : q s.stringif y(form).to String('ut f8')
  1125       return  this
  1126     }
  1127     // creat e form-dat a object
  1128     this._fo rm = new F ormData()
  1129     return t his._form
  1130   }
  1131   Request.pr ototype.mu ltipart =  function ( multipart)  {
  1132     var self  = this
  1133     self.bod y = []
  1134  
  1135     if (!sel f.hasHeade r('content -type')) {
  1136       self.s etHeader(' content-ty pe', 'mult ipart/rela ted; bound ary=' + se lf.boundar y)
  1137     } else {
  1138       var he aderName =  self.hasH eader('con tent-type' );
  1139       self.s etHeader(h eaderName,  self.head ers[header Name].spli t(';')[0]  + '; bound ary=' + se lf.boundar y)
  1140     }
  1141  
  1142     if (!mul tipart.for Each) thro w new Erro r('Argumen t error, o ptions.mul tipart.')
  1143  
  1144     if (self .preambleC RLF) {
  1145       self.b ody.push(n ew Buffer( '\r\n'))
  1146     }
  1147  
  1148     multipar t.forEach( function ( part) {
  1149       var bo dy = part. body
  1150       if(bod y == null)  throw Err or('Body a ttribute m issing in  multipart. ')
  1151       delete  part.body
  1152       var pr eamble = ' --' + self .boundary  + '\r\n'
  1153       Object .keys(part ).forEach( function ( key) {
  1154         prea mble += ke y + ': ' +  part[key]  + '\r\n'
  1155       })
  1156       preamb le += '\r\ n'
  1157       self.b ody.push(n ew Buffer( preamble))
  1158       self.b ody.push(n ew Buffer( body))
  1159       self.b ody.push(n ew Buffer( '\r\n'))
  1160     })
  1161     self.bod y.push(new  Buffer('- -' + self. boundary +  '--'))
  1162     return s elf
  1163   }
  1164   Request.pr ototype.js on = funct ion (val)  {
  1165     var self  = this
  1166  
  1167     if (!sel f.hasHeade r('accept' )) self.se tHeader('a ccept', 'a pplication /json')
  1168  
  1169     this._js on = true
  1170     if (type of val ===  'boolean' ) {
  1171       if (ty peof this. body === ' object') {
  1172         this .body = sa feStringif y(this.bod y)
  1173         if ( !self.hasH eader('con tent-type' ))
  1174           se lf.setHead er('conten t-type', ' applicatio n/json')
  1175       }
  1176     } else {
  1177       this.b ody = safe Stringify( val)
  1178       if (!s elf.hasHea der('conte nt-type'))
  1179         self .setHeader ('content- type', 'ap plication/ json')
  1180     }
  1181  
  1182     return t his
  1183   }
  1184   Request.pr ototype.ge tHeader =  function ( name, head ers) {
  1185     var resu lt, re, ma tch
  1186     if (!hea ders) head ers = this .headers
  1187     Object.k eys(header s).forEach (function  (key) {
  1188       if (ke y.length ! == name.le ngth) retu rn
  1189       re = n ew RegExp( name, 'i')
  1190       match  = key.matc h(re)
  1191       if (ma tch) resul t = header s[key]
  1192     })
  1193     return r esult
  1194   }
  1195   var getHea der = Requ est.protot ype.getHea der
  1196  
  1197   Request.pr ototype.au th = funct ion (user,  pass, sen dImmediate ly, bearer ) {
  1198     if (bear er !== und efined) {
  1199       this._ bearer = b earer
  1200       this._ hasAuth =  true
  1201       if (se ndImmediat ely || typ eof sendIm mediately  == 'undefi ned') {
  1202         if ( typeof bea rer === 'f unction')  {
  1203           be arer = bea rer()
  1204         }
  1205         this .setHeader ('authoriz ation', 'B earer ' +  bearer)
  1206         this ._sentAuth  = true
  1207       }
  1208       return  this
  1209     }
  1210     if (type of user != = 'string'  || (pass  !== undefi ned && typ eof pass ! == 'string ')) {
  1211       throw  new Error( 'auth() re ceived inv alid user  or passwor d')
  1212     }
  1213     this._us er = user
  1214     this._pa ss = pass
  1215     this._ha sAuth = tr ue
  1216     var head er = typeo f pass !==  'undefine d' ? user  + ':' + pa ss : user
  1217     if (send Immediatel y || typeo f sendImme diately ==  'undefine d') {
  1218       this.s etHeader(' authorizat ion', 'Bas ic ' + toB ase64(head er))
  1219       this._ sentAuth =  true
  1220     }
  1221     return t his
  1222   }
  1223   Request.pr ototype.aw s = functi on (opts,  now) {
  1224     if (!now ) {
  1225       this._ aws = opts
  1226       return  this
  1227     }
  1228     var date  = new Dat e()
  1229     this.set Header('da te', date. toUTCStrin g())
  1230     var auth  =
  1231       { key:  opts.key
  1232       , secr et: opts.s ecret
  1233       , verb : this.met hod.toUppe rCase()
  1234       , date : date
  1235       , cont entType: t his.getHea der('conte nt-type')  || ''
  1236       , md5:  this.getH eader('con tent-md5')  || ''
  1237       , amaz onHeaders:  aws.canon icalizeHea ders(this. headers)
  1238       }
  1239     if (opts .bucket &&  this.path ) {
  1240       auth.r esource =  '/' + opts .bucket +  this.path
  1241     } else i f (opts.bu cket && !t his.path)  {
  1242       auth.r esource =  '/' + opts .bucket
  1243     } else i f (!opts.b ucket && t his.path)  {
  1244       auth.r esource =  this.path
  1245     } else i f (!opts.b ucket && ! this.path)  {
  1246       auth.r esource =  '/'
  1247     }
  1248     auth.res ource = aw s.canonica lizeResour ce(auth.re source)
  1249     this.set Header('au thorizatio n', aws.au thorizatio n(auth))
  1250  
  1251     return t his
  1252   }
  1253   Request.pr ototype.ht tpSignatur e = functi on (opts)  {
  1254     var req  = this
  1255     httpSign ature.sign Request({
  1256       getHea der: funct ion(header ) {
  1257         retu rn getHead er(header,  req.heade rs)
  1258       },
  1259       setHea der: funct ion(header , value) {
  1260         req. setHeader( header, va lue)
  1261       },
  1262       method : this.met hod,
  1263       path:  this.path
  1264     }, opts)
  1265     debug('h ttpSignatu re authori zation', t his.getHea der('autho rization') )
  1266  
  1267     return t his
  1268   }
  1269  
  1270   Request.pr ototype.ha wk = funct ion (opts)  {
  1271     this.set Header('Au thorizatio n', hawk.c lient.head er(this.ur i, this.me thod, opts ).field)
  1272   }
  1273  
  1274   Request.pr ototype.oa uth = func tion (_oau th) {
  1275     var form
  1276     if (this .hasHeader ('content- type') &&
  1277         this .getHeader ('content- type').sli ce(0, 'app lication/x -www-form- urlencoded '.length)  ===
  1278           'a pplication /x-www-for m-urlencod ed'
  1279        ) {
  1280       form =  qs.parse( this.body)
  1281     }
  1282     if (this .uri.query ) {
  1283       form =  qs.parse( this.uri.q uery)
  1284     }
  1285     if (!for m) form =  {}
  1286     var oa =  {}
  1287     for (var  i in form ) oa[i] =  form[i]
  1288     for (var  i in _oau th) oa['oa uth_'+i] =  _oauth[i]
  1289     if (!oa. oauth_vers ion) oa.oa uth_versio n = '1.0'
  1290     if (!oa. oauth_time stamp) oa. oauth_time stamp = Ma th.floor(  Date.now()  / 1000 ). toString()
  1291     if (!oa. oauth_nonc e) oa.oaut h_nonce =  uuid().rep lace(/-/g,  '')
  1292  
  1293     oa.oauth _signature _method =  'HMAC-SHA1 '
  1294  
  1295     var cons umer_secre t = oa.oau th_consume r_secret
  1296     delete o a.oauth_co nsumer_sec ret
  1297     var toke n_secret =  oa.oauth_ token_secr et
  1298     delete o a.oauth_to ken_secret
  1299     var time stamp = oa .oauth_tim estamp
  1300  
  1301     var base url = this .uri.proto col + '//'  + this.ur i.host + t his.uri.pa thname
  1302     var sign ature = oa uth.hmacsi gn(this.me thod, base url, oa, c onsumer_se cret, toke n_secret)
  1303  
  1304     // oa.oa uth_signat ure = sign ature
  1305     for (var  i in form ) {
  1306       if ( i .slice(0,  'oauth_')  in _oauth)  {
  1307         // s kip
  1308       } else  {
  1309         dele te oa['oau th_'+i]
  1310         if ( i !== 'x_a uth_mode')  delete oa [i]
  1311       }
  1312     }
  1313     oa.oauth _timestamp  = timesta mp
  1314     var auth Header = ' OAuth '+Ob ject.keys( oa).sort() .map(funct ion (i) {r eturn i+'= "'+oauth.r fc3986(oa[ i])+'"'}). join(',')
  1315     authHead er += ',oa uth_signat ure="' + o auth.rfc39 86(signatu re) + '"'
  1316     this.set Header('Au thorizatio n', authHe ader)
  1317     return t his
  1318   }
  1319   Request.pr ototype.ja r = functi on (jar) {
  1320     var cook ies
  1321  
  1322     if (this ._redirect sFollowed  === 0) {
  1323       this.o riginalCoo kieHeader  = this.get Header('co okie')
  1324     }
  1325  
  1326     if (!jar ) {
  1327       // dis able cooki es
  1328       cookie s = false
  1329       this._ disableCoo kies = tru e
  1330     } else {
  1331       var ta rgetCookie Jar = (jar  && jar.ge tCookieStr ing)?jar:g lobalCooki eJar;
  1332       var ur ihref = th is.uri.hre f
  1333       //fetc h cookie i n the Spec ified host
  1334       if (ta rgetCookie Jar) {
  1335         cook ies = targ etCookieJa r.getCooki eString(ur ihref);
  1336       }
  1337     }
  1338  
  1339     //if nee d cookie a nd cookie  is not emp ty
  1340     if (cook ies && coo kies.lengt h) {
  1341       if (th is.origina lCookieHea der) {
  1342         // D on't overw rite exist ing Cookie  header
  1343         this .setHeader ('cookie',  this.orig inalCookie Header + ' ; ' + cook ies)
  1344       } else  {
  1345         this .setHeader ('cookie',  cookies)
  1346       }
  1347     }
  1348     this._ja r = jar
  1349     return t his
  1350   }
  1351  
  1352  
  1353   // Stream  API
  1354   Request.pr ototype.pi pe = funct ion (dest,  opts) {
  1355     if (this .response)  {
  1356       if (th is._destda ta) {
  1357         thro w new Erro r("You can not pipe a fter data  has been e mitted fro m the resp onse.")
  1358       } else  if (this. _ended) {
  1359         thro w new Erro r("You can not pipe a fter the r esponse ha s been end ed.")
  1360       } else  {
  1361         stre am.Stream. prototype. pipe.call( this, dest , opts)
  1362         this .pipeDest( dest)
  1363         retu rn dest
  1364       }
  1365     } else {
  1366       this.d ests.push( dest)
  1367       stream .Stream.pr ototype.pi pe.call(th is, dest,  opts)
  1368       return  dest
  1369     }
  1370   }
  1371   Request.pr ototype.wr ite = func tion () {
  1372     if (!thi s._started ) this.sta rt()
  1373     return t his.req.wr ite.apply( this.req,  arguments)
  1374   }
  1375   Request.pr ototype.en d = functi on (chunk)  {
  1376     if (chun k) this.wr ite(chunk)
  1377     if (!thi s._started ) this.sta rt()
  1378     this.req .end()
  1379   }
  1380   Request.pr ototype.pa use = func tion () {
  1381     if (!thi s.response ) this._pa used = tru e
  1382     else thi s.response .pause.app ly(this.re sponse, ar guments)
  1383   }
  1384   Request.pr ototype.re sume = fun ction () {
  1385     if (!thi s.response ) this._pa used = fal se
  1386     else thi s.response .resume.ap ply(this.r esponse, a rguments)
  1387   }
  1388   Request.pr ototype.de stroy = fu nction ()  {
  1389     if (!thi s._ended)  this.end()
  1390     else if  (this.resp onse) this .response. destroy()
  1391   }
  1392  
  1393   function t oJSON () {
  1394     return g etSafe(thi s, '__' +  (((1+Math. random())* 0x10000)|0 ).toString (16))
  1395   }
  1396  
  1397   Request.pr ototype.to JSON = toJ SON
  1398  
  1399  
  1400   module.exp orts = Req uest