26. EPMO Open Source Coordination Office Redaction File Detail Report

Produced by Araxis Merge on 10/24/2017 6:38:26 AM 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.

26.1 Files compared

# Location File Last Modified
1 CHAMP_VA1.zip\CHAMP_VA1\node_modules\gulp-mocha-phantomjs\node_modules\phantomjs\node_modules\request request.js Mon Oct 16 21:06:50 2017 UTC
2 CHAMP_VA1.zip\CHAMP_VA1\node_modules\gulp-mocha-phantomjs\node_modules\phantomjs\node_modules\request request.js Mon Oct 23 19:28:13 2017 UTC

26.2 Comparison summary

Description Between
Files 1 and 2
Text Blocks Lines
Unchanged 4 2714
Changed 3 10
Inserted 0 0
Removed 0 0

26.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

26.4 Active regular expressions

No regular expressions were active.

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