Hex Artifact Content
Not logged in

Artifact 0447082c02c1e61b30b865091871f34977811536:


0000: 27 75 73 65 20 73 74 72 69 63 74 27 0a 0a 76 61  'use strict'..va
0010: 72 20 68 74 74 70 20 3d 20 72 65 71 75 69 72 65  r http = require
0020: 28 27 68 74 74 70 27 29 0a 20 20 2c 20 72 65 71  ('http').  , req
0030: 75 65 73 74 20 3d 20 72 65 71 75 69 72 65 28 27  uest = require('
0040: 2e 2e 2f 69 6e 64 65 78 27 29 0a 20 20 2c 20 74  ../index').  , t
0050: 61 70 65 20 3d 20 72 65 71 75 69 72 65 28 27 74  ape = require('t
0060: 61 70 65 27 29 0a 20 20 2c 20 63 72 79 70 74 6f  ape').  , crypto
0070: 20 3d 20 72 65 71 75 69 72 65 28 27 63 72 79 70   = require('cryp
0080: 74 6f 27 29 0a 0a 66 75 6e 63 74 69 6f 6e 20 6d  to')..function m
0090: 61 6b 65 48 65 61 64 65 72 28 29 20 7b 0a 20 20  akeHeader() {.  
00a0: 72 65 74 75 72 6e 20 5b 5d 2e 6a 6f 69 6e 2e 63  return [].join.c
00b0: 61 6c 6c 28 61 72 67 75 6d 65 6e 74 73 2c 20 27  all(arguments, '
00c0: 2c 20 27 29 0a 7d 0a 0a 66 75 6e 63 74 69 6f 6e  , ').}..function
00d0: 20 6d 61 6b 65 48 65 61 64 65 72 52 65 67 65 78   makeHeaderRegex
00e0: 28 29 20 7b 0a 20 20 72 65 74 75 72 6e 20 6e 65  () {.  return ne
00f0: 77 20 52 65 67 45 78 70 28 27 5e 27 20 2b 20 6d  w RegExp('^' + m
0100: 61 6b 65 48 65 61 64 65 72 2e 61 70 70 6c 79 28  akeHeader.apply(
0110: 6e 75 6c 6c 2c 20 61 72 67 75 6d 65 6e 74 73 29  null, arguments)
0120: 20 2b 20 27 24 27 29 0a 7d 0a 0a 66 75 6e 63 74   + '$').}..funct
0130: 69 6f 6e 20 6d 64 35 20 28 73 74 72 29 20 7b 0a  ion md5 (str) {.
0140: 20 20 72 65 74 75 72 6e 20 63 72 79 70 74 6f 2e    return crypto.
0150: 63 72 65 61 74 65 48 61 73 68 28 27 6d 64 35 27  createHash('md5'
0160: 29 2e 75 70 64 61 74 65 28 73 74 72 29 2e 64 69  ).update(str).di
0170: 67 65 73 74 28 27 68 65 78 27 29 0a 7d 0a 0a 76  gest('hex').}..v
0180: 61 72 20 64 69 67 65 73 74 53 65 72 76 65 72 20  ar digestServer 
0190: 3d 20 68 74 74 70 2e 63 72 65 61 74 65 53 65 72  = http.createSer
01a0: 76 65 72 28 66 75 6e 63 74 69 6f 6e 28 72 65 71  ver(function(req
01b0: 2c 20 72 65 73 29 20 7b 0a 20 20 76 61 72 20 6f  , res) {.  var o
01c0: 6b 0a 20 20 20 20 2c 20 74 65 73 74 48 65 61 64  k.    , testHead
01d0: 65 72 0a 0a 20 20 69 66 20 28 72 65 71 2e 75 72  er..  if (req.ur
01e0: 6c 20 3d 3d 3d 20 27 2f 74 65 73 74 2f 27 29 20  l === '/test/') 
01f0: 7b 0a 20 20 20 20 69 66 20 28 72 65 71 2e 68 65  {.    if (req.he
0200: 61 64 65 72 73 2e 61 75 74 68 6f 72 69 7a 61 74  aders.authorizat
0210: 69 6f 6e 29 20 7b 0a 20 20 20 20 20 20 74 65 73  ion) {.      tes
0220: 74 48 65 61 64 65 72 20 3d 20 6d 61 6b 65 48 65  tHeader = makeHe
0230: 61 64 65 72 52 65 67 65 78 28 0a 20 20 20 20 20  aderRegex(.     
0240: 20 20 20 20 20 27 44 69 67 65 73 74 20 75 73 65       'Digest use
0250: 72 6e 61 6d 65 3d 22 74 65 73 74 22 27 2c 0a 20  rname="test"',. 
0260: 20 20 20 20 20 20 20 20 20 27 72 65 61 6c 6d 3d           'realm=
0270: 22 50 72 69 76 61 74 65 22 27 2c 0a 20 20 20 20  "Private"',.    
0280: 20 20 20 20 20 20 27 6e 6f 6e 63 65 3d 22 57 70        'nonce="Wp
0290: 63 48 53 32 2f 54 42 41 41 3d 64 66 66 63 63 30  cHS2/TBAA=dffcc0
02a0: 64 62 64 35 66 39 36 64 34 39 61 35 34 37 37 31  dbd5f96d49a54771
02b0: 36 36 36 34 39 62 37 63 30 61 65 33 38 36 36 61  66649b7c0ae3866a
02c0: 39 33 22 27 2c 0a 20 20 20 20 20 20 20 20 20 20  93"',.          
02d0: 27 75 72 69 3d 22 2f 74 65 73 74 2f 22 27 2c 0a  'uri="/test/"',.
02e0: 20 20 20 20 20 20 20 20 20 20 27 71 6f 70 3d 61            'qop=a
02f0: 75 74 68 27 2c 0a 20 20 20 20 20 20 20 20 20 20  uth',.          
0300: 27 72 65 73 70 6f 6e 73 65 3d 22 5b 61 2d 66 30  'response="[a-f0
0310: 2d 39 5d 7b 33 32 7d 22 27 2c 0a 20 20 20 20 20  -9]{32}"',.     
0320: 20 20 20 20 20 27 6e 63 3d 30 30 30 30 30 30 30       'nc=0000000
0330: 31 27 2c 0a 20 20 20 20 20 20 20 20 20 20 27 63  1',.          'c
0340: 6e 6f 6e 63 65 3d 22 5b 61 2d 66 30 2d 39 5d 7b  nonce="[a-f0-9]{
0350: 33 32 7d 22 27 2c 0a 20 20 20 20 20 20 20 20 20  32}"',.         
0360: 20 27 61 6c 67 6f 72 69 74 68 6d 3d 4d 44 35 27   'algorithm=MD5'
0370: 2c 0a 20 20 20 20 20 20 20 20 20 20 27 6f 70 61  ,.          'opa
0380: 71 75 65 3d 22 35 63 63 63 30 36 39 63 34 30 33  que="5ccc069c403
0390: 65 62 61 66 39 66 30 31 37 31 65 39 35 31 37 66  ebaf9f0171e9517f
03a0: 34 30 65 34 31 22 27 0a 20 20 20 20 20 20 29 0a  40e41"'.      ).
03b0: 20 20 20 20 20 20 69 66 20 28 74 65 73 74 48 65        if (testHe
03c0: 61 64 65 72 2e 74 65 73 74 28 72 65 71 2e 68 65  ader.test(req.he
03d0: 61 64 65 72 73 2e 61 75 74 68 6f 72 69 7a 61 74  aders.authorizat
03e0: 69 6f 6e 29 29 20 7b 0a 20 20 20 20 20 20 20 20  ion)) {.        
03f0: 6f 6b 20 3d 20 74 72 75 65 0a 20 20 20 20 20 20  ok = true.      
0400: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20  } else {.       
0410: 20 2f 2f 20 42 61 64 20 61 75 74 68 20 68 65 61   // Bad auth hea
0420: 64 65 72 2c 20 64 6f 6e 27 74 20 73 65 6e 64 20  der, don't send 
0430: 62 61 63 6b 20 57 57 57 2d 41 75 74 68 65 6e 74  back WWW-Authent
0440: 69 63 61 74 65 20 68 65 61 64 65 72 0a 20 20 20  icate header.   
0450: 20 20 20 20 20 6f 6b 20 3d 20 66 61 6c 73 65 0a       ok = false.
0460: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 20 65 6c        }.    } el
0470: 73 65 20 7b 0a 20 20 20 20 20 20 2f 2f 20 4e 6f  se {.      // No
0480: 20 61 75 74 68 20 68 65 61 64 65 72 2c 20 73 65   auth header, se
0490: 6e 64 20 62 61 63 6b 20 57 57 57 2d 41 75 74 68  nd back WWW-Auth
04a0: 65 6e 74 69 63 61 74 65 20 68 65 61 64 65 72 0a  enticate header.
04b0: 20 20 20 20 20 20 6f 6b 20 3d 20 66 61 6c 73 65        ok = false
04c0: 0a 20 20 20 20 20 20 72 65 73 2e 73 65 74 48 65  .      res.setHe
04d0: 61 64 65 72 28 27 77 77 77 2d 61 75 74 68 65 6e  ader('www-authen
04e0: 74 69 63 61 74 65 27 2c 20 6d 61 6b 65 48 65 61  ticate', makeHea
04f0: 64 65 72 28 0a 20 20 20 20 20 20 20 20 20 20 27  der(.          '
0500: 44 69 67 65 73 74 20 72 65 61 6c 6d 3d 22 50 72  Digest realm="Pr
0510: 69 76 61 74 65 22 27 2c 0a 20 20 20 20 20 20 20  ivate"',.       
0520: 20 20 20 27 6e 6f 6e 63 65 3d 22 57 70 63 48 53     'nonce="WpcHS
0530: 32 2f 54 42 41 41 3d 64 66 66 63 63 30 64 62 64  2/TBAA=dffcc0dbd
0540: 35 66 39 36 64 34 39 61 35 34 37 37 31 36 36 36  5f96d49a54771666
0550: 34 39 62 37 63 30 61 65 33 38 36 36 61 39 33 22  49b7c0ae3866a93"
0560: 27 2c 0a 20 20 20 20 20 20 20 20 20 20 27 61 6c  ',.          'al
0570: 67 6f 72 69 74 68 6d 3d 4d 44 35 27 2c 0a 20 20  gorithm=MD5',.  
0580: 20 20 20 20 20 20 20 20 27 71 6f 70 3d 22 61 75          'qop="au
0590: 74 68 22 27 2c 0a 20 20 20 20 20 20 20 20 20 20  th"',.          
05a0: 27 6f 70 61 71 75 65 3d 22 35 63 63 63 30 36 39  'opaque="5ccc069
05b0: 63 34 30 33 65 62 61 66 39 66 30 31 37 31 65 39  c403ebaf9f0171e9
05c0: 35 31 37 66 34 30 65 34 31 22 27 0a 20 20 20 20  517f40e41"'.    
05d0: 20 20 29 29 0a 20 20 20 20 7d 0a 20 20 7d 20 65    )).    }.  } e
05e0: 6c 73 65 20 69 66 20 28 72 65 71 2e 75 72 6c 20  lse if (req.url 
05f0: 3d 3d 3d 20 27 2f 74 65 73 74 2f 6d 64 35 2d 73  === '/test/md5-s
0600: 65 73 73 27 29 20 7b 20 2f 2f 20 52 46 43 20 32  ess') { // RFC 2
0610: 37 31 36 20 4d 44 35 2d 73 65 73 73 20 77 2f 20  716 MD5-sess w/ 
0620: 71 6f 70 3d 61 75 74 68 0a 20 20 20 20 76 61 72  qop=auth.    var
0630: 20 75 73 65 72 20 3d 20 27 74 65 73 74 27 0a 20   user = 'test'. 
0640: 20 20 20 76 61 72 20 72 65 61 6c 6d 20 3d 20 27     var realm = '
0650: 50 72 69 76 61 74 65 27 0a 20 20 20 20 76 61 72  Private'.    var
0660: 20 70 61 73 73 20 3d 20 27 74 65 73 74 69 6e 67   pass = 'testing
0670: 27 0a 20 20 20 20 76 61 72 20 6e 6f 6e 63 65 20  '.    var nonce 
0680: 3d 20 27 57 70 63 48 53 32 2f 54 42 41 41 3d 64  = 'WpcHS2/TBAA=d
0690: 66 66 63 63 30 64 62 64 35 66 39 36 64 34 39 61  ffcc0dbd5f96d49a
06a0: 35 34 37 37 31 36 36 36 34 39 62 37 63 30 61 65  5477166649b7c0ae
06b0: 33 38 36 36 61 39 33 27 0a 20 20 20 20 76 61 72  3866a93'.    var
06c0: 20 6e 6f 6e 63 65 43 6f 75 6e 74 20 3d 20 27 30   nonceCount = '0
06d0: 30 30 30 30 30 30 31 27 0a 20 20 20 20 76 61 72  0000001'.    var
06e0: 20 71 6f 70 20 3d 20 27 61 75 74 68 27 0a 20 20   qop = 'auth'.  
06f0: 20 20 76 61 72 20 61 6c 67 6f 72 69 74 68 6d 20    var algorithm 
0700: 3d 20 27 4d 44 35 2d 73 65 73 73 27 0a 20 20 20  = 'MD5-sess'.   
0710: 20 69 66 20 28 72 65 71 2e 68 65 61 64 65 72 73   if (req.headers
0720: 2e 61 75 74 68 6f 72 69 7a 61 74 69 6f 6e 29 20  .authorization) 
0730: 7b 0a 0a 20 20 20 20 20 20 2f 2f 48 41 31 3d 4d  {..      //HA1=M
0740: 44 35 28 4d 44 35 28 75 73 65 72 6e 61 6d 65 3a  D5(MD5(username:
0750: 72 65 61 6c 6d 3a 70 61 73 73 77 6f 72 64 29 3a  realm:password):
0760: 6e 6f 6e 63 65 3a 63 6e 6f 6e 63 65 29 0a 20 20  nonce:cnonce).  
0770: 20 20 20 20 2f 2f 48 41 32 3d 4d 44 35 28 6d 65      //HA2=MD5(me
0780: 74 68 6f 64 3a 64 69 67 65 73 74 55 52 49 29 0a  thod:digestURI).
0790: 20 20 20 20 20 20 2f 2f 72 65 73 70 6f 6e 73 65        //response
07a0: 3d 4d 44 35 28 48 41 31 3a 6e 6f 6e 63 65 3a 6e  =MD5(HA1:nonce:n
07b0: 6f 6e 63 65 43 6f 75 6e 74 3a 63 6c 69 65 6e 74  onceCount:client
07c0: 4e 6f 6e 63 65 3a 71 6f 70 3a 48 41 32 29 0a 0a  Nonce:qop:HA2)..
07d0: 20 20 20 20 20 20 76 61 72 20 63 6e 6f 6e 63 65        var cnonce
07e0: 20 3d 20 2f 63 6e 6f 6e 63 65 3d 22 28 2e 2a 29   = /cnonce="(.*)
07f0: 22 2f 2e 65 78 65 63 28 72 65 71 2e 68 65 61 64  "/.exec(req.head
0800: 65 72 73 2e 61 75 74 68 6f 72 69 7a 61 74 69 6f  ers.authorizatio
0810: 6e 29 5b 31 5d 0a 20 20 20 20 20 20 76 61 72 20  n)[1].      var 
0820: 68 61 31 20 3d 20 6d 64 35 28 6d 64 35 28 75 73  ha1 = md5(md5(us
0830: 65 72 20 2b 20 27 3a 27 20 2b 20 72 65 61 6c 6d  er + ':' + realm
0840: 20 2b 20 27 3a 27 20 2b 20 70 61 73 73 29 20 2b   + ':' + pass) +
0850: 20 27 3a 27 20 2b 20 6e 6f 6e 63 65 20 2b 20 27   ':' + nonce + '
0860: 3a 27 20 2b 20 63 6e 6f 6e 63 65 29 0a 20 20 20  :' + cnonce).   
0870: 20 20 20 76 61 72 20 68 61 32 20 3d 20 6d 64 35     var ha2 = md5
0880: 28 27 47 45 54 3a 2f 74 65 73 74 2f 6d 64 35 2d  ('GET:/test/md5-
0890: 73 65 73 73 27 29 0a 20 20 20 20 20 20 76 61 72  sess').      var
08a0: 20 72 65 73 70 6f 6e 73 65 20 3d 20 6d 64 35 28   response = md5(
08b0: 68 61 31 20 2b 20 27 3a 27 20 2b 20 6e 6f 6e 63  ha1 + ':' + nonc
08c0: 65 20 2b 20 27 3a 27 20 2b 20 6e 6f 6e 63 65 43  e + ':' + nonceC
08d0: 6f 75 6e 74 20 2b 20 27 3a 27 20 2b 20 63 6e 6f  ount + ':' + cno
08e0: 6e 63 65 20 2b 20 27 3a 27 20 2b 20 71 6f 70 20  nce + ':' + qop 
08f0: 2b 20 27 3a 27 20 2b 20 68 61 32 29 0a 0a 20 20  + ':' + ha2)..  
0900: 20 20 20 20 74 65 73 74 48 65 61 64 65 72 20 3d      testHeader =
0910: 20 6d 61 6b 65 48 65 61 64 65 72 52 65 67 65 78   makeHeaderRegex
0920: 28 0a 20 20 20 20 20 20 20 20 20 20 27 44 69 67  (.          'Dig
0930: 65 73 74 20 75 73 65 72 6e 61 6d 65 3d 22 27 20  est username="' 
0940: 2b 20 75 73 65 72 20 2b 20 27 22 27 2c 0a 20 20  + user + '"',.  
0950: 20 20 20 20 20 20 20 20 27 72 65 61 6c 6d 3d 22          'realm="
0960: 27 20 2b 20 72 65 61 6c 6d 20 2b 20 27 22 27 2c  ' + realm + '"',
0970: 0a 20 20 20 20 20 20 20 20 20 20 27 6e 6f 6e 63  .          'nonc
0980: 65 3d 22 27 20 2b 20 6e 6f 6e 63 65 20 2b 20 27  e="' + nonce + '
0990: 22 27 2c 0a 20 20 20 20 20 20 20 20 20 20 27 75  "',.          'u
09a0: 72 69 3d 22 2f 74 65 73 74 2f 6d 64 35 2d 73 65  ri="/test/md5-se
09b0: 73 73 22 27 2c 0a 20 20 20 20 20 20 20 20 20 20  ss"',.          
09c0: 27 71 6f 70 3d 27 20 2b 20 71 6f 70 2c 0a 20 20  'qop=' + qop,.  
09d0: 20 20 20 20 20 20 20 20 27 72 65 73 70 6f 6e 73          'respons
09e0: 65 3d 22 27 20 2b 20 72 65 73 70 6f 6e 73 65 20  e="' + response 
09f0: 2b 20 27 22 27 2c 0a 20 20 20 20 20 20 20 20 20  + '"',.         
0a00: 20 27 6e 63 3d 27 20 2b 20 6e 6f 6e 63 65 43 6f   'nc=' + nonceCo
0a10: 75 6e 74 2c 0a 20 20 20 20 20 20 20 20 20 20 27  unt,.          '
0a20: 63 6e 6f 6e 63 65 3d 22 27 20 2b 20 63 6e 6f 6e  cnonce="' + cnon
0a30: 63 65 20 2b 20 27 22 27 2c 0a 20 20 20 20 20 20  ce + '"',.      
0a40: 20 20 20 20 27 61 6c 67 6f 72 69 74 68 6d 3d 27      'algorithm='
0a50: 20 2b 20 61 6c 67 6f 72 69 74 68 6d 0a 20 20 20   + algorithm.   
0a60: 20 20 20 29 0a 0a 20 20 20 20 20 20 6f 6b 20 3d     )..      ok =
0a70: 20 74 65 73 74 48 65 61 64 65 72 2e 74 65 73 74   testHeader.test
0a80: 28 72 65 71 2e 68 65 61 64 65 72 73 2e 61 75 74  (req.headers.aut
0a90: 68 6f 72 69 7a 61 74 69 6f 6e 29 0a 20 20 20 20  horization).    
0aa0: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 2f  } else {.      /
0ab0: 2f 20 4e 6f 20 61 75 74 68 20 68 65 61 64 65 72  / No auth header
0ac0: 2c 20 73 65 6e 64 20 62 61 63 6b 20 57 57 57 2d  , send back WWW-
0ad0: 41 75 74 68 65 6e 74 69 63 61 74 65 20 68 65 61  Authenticate hea
0ae0: 64 65 72 0a 20 20 20 20 20 20 6f 6b 20 3d 20 66  der.      ok = f
0af0: 61 6c 73 65 0a 20 20 20 20 20 20 72 65 73 2e 73  alse.      res.s
0b00: 65 74 48 65 61 64 65 72 28 27 77 77 77 2d 61 75  etHeader('www-au
0b10: 74 68 65 6e 74 69 63 61 74 65 27 2c 20 6d 61 6b  thenticate', mak
0b20: 65 48 65 61 64 65 72 28 0a 20 20 20 20 20 20 20  eHeader(.       
0b30: 20 20 20 27 44 69 67 65 73 74 20 72 65 61 6c 6d     'Digest realm
0b40: 3d 22 27 20 2b 20 72 65 61 6c 6d 20 2b 20 27 22  ="' + realm + '"
0b50: 27 2c 0a 20 20 20 20 20 20 20 20 20 20 27 6e 6f  ',.          'no
0b60: 6e 63 65 3d 22 27 20 2b 20 6e 6f 6e 63 65 20 2b  nce="' + nonce +
0b70: 20 27 22 27 2c 0a 20 20 20 20 20 20 20 20 20 20   '"',.          
0b80: 27 61 6c 67 6f 72 69 74 68 6d 3d 27 20 2b 20 61  'algorithm=' + a
0b90: 6c 67 6f 72 69 74 68 6d 2c 0a 20 20 20 20 20 20  lgorithm,.      
0ba0: 20 20 20 20 27 71 6f 70 3d 22 27 20 2b 20 71 6f      'qop="' + qo
0bb0: 70 20 2b 20 27 22 27 0a 20 20 20 20 20 20 29 29  p + '"'.      ))
0bc0: 0a 20 20 20 20 7d 0a 20 20 7d 20 65 6c 73 65 20  .    }.  } else 
0bd0: 69 66 20 28 72 65 71 2e 75 72 6c 20 3d 3d 3d 20  if (req.url === 
0be0: 27 2f 64 69 72 2f 69 6e 64 65 78 2e 68 74 6d 6c  '/dir/index.html
0bf0: 27 29 20 7b 0a 20 20 20 20 2f 2f 20 52 46 43 32  ') {.    // RFC2
0c00: 30 36 39 2d 63 6f 6d 70 61 74 69 62 6c 65 20 6d  069-compatible m
0c10: 6f 64 65 0a 20 20 20 20 2f 2f 20 63 68 65 63 6b  ode.    // check
0c20: 3a 20 68 74 74 70 3a 2f 2f 77 77 77 2e 72 66 63  : http://www.rfc
0c30: 2d 65 64 69 74 6f 72 2e 6f 72 67 2f 65 72 72 61  -editor.org/erra
0c40: 74 61 5f 73 65 61 72 63 68 2e 70 68 70 3f 72 66  ta_search.php?rf
0c50: 63 3d 32 30 36 39 0a 20 20 20 20 69 66 20 28 72  c=2069.    if (r
0c60: 65 71 2e 68 65 61 64 65 72 73 2e 61 75 74 68 6f  eq.headers.autho
0c70: 72 69 7a 61 74 69 6f 6e 29 20 7b 0a 20 20 20 20  rization) {.    
0c80: 20 20 74 65 73 74 48 65 61 64 65 72 20 3d 20 6d    testHeader = m
0c90: 61 6b 65 48 65 61 64 65 72 52 65 67 65 78 28 0a  akeHeaderRegex(.
0ca0: 20 20 20 20 20 20 20 20 27 44 69 67 65 73 74 20          'Digest 
0cb0: 75 73 65 72 6e 61 6d 65 3d 22 4d 75 66 61 73 61  username="Mufasa
0cc0: 22 27 2c 0a 20 20 20 20 20 20 20 20 27 72 65 61  "',.        'rea
0cd0: 6c 6d 3d 22 74 65 73 74 72 65 61 6c 6d 40 68 6f  lm="testrealm@ho
0ce0: 73 74 2e 63 6f 6d 22 27 2c 0a 20 20 20 20 20 20  st.com"',.      
0cf0: 20 20 27 6e 6f 6e 63 65 3d 22 64 63 64 39 38 62    'nonce="dcd98b
0d00: 37 31 30 32 64 64 32 66 30 65 38 62 31 31 64 30  7102dd2f0e8b11d0
0d10: 66 36 30 30 62 66 62 30 63 30 39 33 22 27 2c 0a  f600bfb0c093"',.
0d20: 20 20 20 20 20 20 20 20 27 75 72 69 3d 22 2f 64          'uri="/d
0d30: 69 72 2f 69 6e 64 65 78 2e 68 74 6d 6c 22 27 2c  ir/index.html"',
0d40: 0a 20 20 20 20 20 20 20 20 27 72 65 73 70 6f 6e  .        'respon
0d50: 73 65 3d 22 5b 61 2d 66 30 2d 39 5d 7b 33 32 7d  se="[a-f0-9]{32}
0d60: 22 27 2c 0a 20 20 20 20 20 20 20 20 27 6f 70 61  "',.        'opa
0d70: 71 75 65 3d 22 35 63 63 63 30 36 39 63 34 30 33  que="5ccc069c403
0d80: 65 62 61 66 39 66 30 31 37 31 65 39 35 31 37 66  ebaf9f0171e9517f
0d90: 34 30 65 34 31 22 27 0a 20 20 20 20 20 20 29 0a  40e41"'.      ).
0da0: 20 20 20 20 20 20 69 66 20 28 74 65 73 74 48 65        if (testHe
0db0: 61 64 65 72 2e 74 65 73 74 28 72 65 71 2e 68 65  ader.test(req.he
0dc0: 61 64 65 72 73 2e 61 75 74 68 6f 72 69 7a 61 74  aders.authorizat
0dd0: 69 6f 6e 29 29 20 7b 0a 20 20 20 20 20 20 20 20  ion)) {.        
0de0: 6f 6b 20 3d 20 74 72 75 65 0a 20 20 20 20 20 20  ok = true.      
0df0: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 20 20 20  } else {.       
0e00: 20 2f 2f 20 42 61 64 20 61 75 74 68 20 68 65 61   // Bad auth hea
0e10: 64 65 72 2c 20 64 6f 6e 27 74 20 73 65 6e 64 20  der, don't send 
0e20: 62 61 63 6b 20 57 57 57 2d 41 75 74 68 65 6e 74  back WWW-Authent
0e30: 69 63 61 74 65 20 68 65 61 64 65 72 0a 20 20 20  icate header.   
0e40: 20 20 20 20 20 6f 6b 20 3d 20 66 61 6c 73 65 0a       ok = false.
0e50: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 20 65 6c        }.    } el
0e60: 73 65 20 7b 0a 20 20 20 20 20 20 2f 2f 20 4e 6f  se {.      // No
0e70: 20 61 75 74 68 20 68 65 61 64 65 72 2c 20 73 65   auth header, se
0e80: 6e 64 20 62 61 63 6b 20 57 57 57 2d 41 75 74 68  nd back WWW-Auth
0e90: 65 6e 74 69 63 61 74 65 20 68 65 61 64 65 72 0a  enticate header.
0ea0: 20 20 20 20 20 20 6f 6b 20 3d 20 66 61 6c 73 65        ok = false
0eb0: 0a 20 20 20 20 20 20 72 65 73 2e 73 65 74 48 65  .      res.setHe
0ec0: 61 64 65 72 28 27 77 77 77 2d 61 75 74 68 65 6e  ader('www-authen
0ed0: 74 69 63 61 74 65 27 2c 20 6d 61 6b 65 48 65 61  ticate', makeHea
0ee0: 64 65 72 28 0a 20 20 20 20 20 20 20 20 27 44 69  der(.        'Di
0ef0: 67 65 73 74 20 72 65 61 6c 6d 3d 22 74 65 73 74  gest realm="test
0f00: 72 65 61 6c 6d 40 68 6f 73 74 2e 63 6f 6d 22 27  realm@host.com"'
0f10: 2c 0a 20 20 20 20 20 20 20 20 27 6e 6f 6e 63 65  ,.        'nonce
0f20: 3d 22 64 63 64 39 38 62 37 31 30 32 64 64 32 66  ="dcd98b7102dd2f
0f30: 30 65 38 62 31 31 64 30 66 36 30 30 62 66 62 30  0e8b11d0f600bfb0
0f40: 63 30 39 33 22 27 2c 0a 20 20 20 20 20 20 20 20  c093"',.        
0f50: 27 6f 70 61 71 75 65 3d 22 35 63 63 63 30 36 39  'opaque="5ccc069
0f60: 63 34 30 33 65 62 61 66 39 66 30 31 37 31 65 39  c403ebaf9f0171e9
0f70: 35 31 37 66 34 30 65 34 31 22 27 0a 20 20 20 20  517f40e41"'.    
0f80: 20 20 29 29 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a    )).    }.  }..
0f90: 20 20 69 66 20 28 6f 6b 29 20 7b 0a 20 20 20 20    if (ok) {.    
0fa0: 72 65 73 2e 65 6e 64 28 27 6f 6b 27 29 0a 20 20  res.end('ok').  
0fb0: 7d 20 65 6c 73 65 20 7b 0a 20 20 20 20 72 65 73  } else {.    res
0fc0: 2e 73 74 61 74 75 73 43 6f 64 65 20 3d 20 34 30  .statusCode = 40
0fd0: 31 0a 20 20 20 20 72 65 73 2e 65 6e 64 28 27 34  1.    res.end('4
0fe0: 30 31 27 29 0a 20 20 7d 0a 7d 29 0a 0a 74 61 70  01').  }.})..tap
0ff0: 65 28 27 73 65 74 75 70 27 2c 20 66 75 6e 63 74  e('setup', funct
1000: 69 6f 6e 28 74 29 20 7b 0a 20 20 64 69 67 65 73  ion(t) {.  diges
1010: 74 53 65 72 76 65 72 2e 6c 69 73 74 65 6e 28 36  tServer.listen(6
1020: 37 36 37 2c 20 66 75 6e 63 74 69 6f 6e 28 29 20  767, function() 
1030: 7b 0a 20 20 20 20 74 2e 65 6e 64 28 29 0a 20 20  {.    t.end().  
1040: 7d 29 0a 7d 29 0a 0a 74 61 70 65 28 27 77 69 74  }).})..tape('wit
1050: 68 20 73 65 6e 64 49 6d 6d 65 64 69 61 74 65 6c  h sendImmediatel
1060: 79 20 3d 20 66 61 6c 73 65 27 2c 20 66 75 6e 63  y = false', func
1070: 74 69 6f 6e 28 74 29 20 7b 0a 20 20 76 61 72 20  tion(t) {.  var 
1080: 6e 75 6d 52 65 64 69 72 65 63 74 73 20 3d 20 30  numRedirects = 0
1090: 0a 0a 20 20 72 65 71 75 65 73 74 28 7b 0a 20 20  ..  request({.  
10a0: 20 20 6d 65 74 68 6f 64 3a 20 27 47 45 54 27 2c    method: 'GET',
10b0: 0a 20 20 20 20 75 72 69 3a 20 27 68 74 74 70 3a  .    uri: 'http:
10c0: 2f 2f 6c 6f 63 61 6c 68 6f 73 74 3a 36 37 36 37  //localhost:6767
10d0: 2f 74 65 73 74 2f 27 2c 0a 20 20 20 20 61 75 74  /test/',.    aut
10e0: 68 3a 20 7b 0a 20 20 20 20 20 20 75 73 65 72 3a  h: {.      user:
10f0: 20 27 74 65 73 74 27 2c 0a 20 20 20 20 20 20 70   'test',.      p
1100: 61 73 73 3a 20 27 74 65 73 74 69 6e 67 27 2c 0a  ass: 'testing',.
1110: 20 20 20 20 20 20 73 65 6e 64 49 6d 6d 65 64 69        sendImmedi
1120: 61 74 65 6c 79 3a 20 66 61 6c 73 65 0a 20 20 20  ately: false.   
1130: 20 7d 0a 20 20 7d 2c 20 66 75 6e 63 74 69 6f 6e   }.  }, function
1140: 28 65 72 72 6f 72 2c 20 72 65 73 70 6f 6e 73 65  (error, response
1150: 2c 20 62 6f 64 79 29 20 7b 0a 20 20 20 20 74 2e  , body) {.    t.
1160: 65 71 75 61 6c 28 65 72 72 6f 72 2c 20 6e 75 6c  equal(error, nul
1170: 6c 29 0a 20 20 20 20 74 2e 65 71 75 61 6c 28 72  l).    t.equal(r
1180: 65 73 70 6f 6e 73 65 2e 73 74 61 74 75 73 43 6f  esponse.statusCo
1190: 64 65 2c 20 32 30 30 29 0a 20 20 20 20 74 2e 65  de, 200).    t.e
11a0: 71 75 61 6c 28 6e 75 6d 52 65 64 69 72 65 63 74  qual(numRedirect
11b0: 73 2c 20 31 29 0a 20 20 20 20 74 2e 65 6e 64 28  s, 1).    t.end(
11c0: 29 0a 20 20 7d 29 2e 6f 6e 28 27 72 65 64 69 72  ).  }).on('redir
11d0: 65 63 74 27 2c 20 66 75 6e 63 74 69 6f 6e 28 29  ect', function()
11e0: 20 7b 0a 20 20 20 20 74 2e 65 71 75 61 6c 28 74   {.    t.equal(t
11f0: 68 69 73 2e 72 65 73 70 6f 6e 73 65 2e 73 74 61  his.response.sta
1200: 74 75 73 43 6f 64 65 2c 20 34 30 31 29 0a 20 20  tusCode, 401).  
1210: 20 20 6e 75 6d 52 65 64 69 72 65 63 74 73 2b 2b    numRedirects++
1220: 0a 20 20 7d 29 0a 7d 29 0a 0a 74 61 70 65 28 27  .  }).})..tape('
1230: 77 69 74 68 20 4d 44 35 2d 73 65 73 73 20 61 6c  with MD5-sess al
1240: 67 6f 72 69 74 68 6d 27 2c 20 66 75 6e 63 74 69  gorithm', functi
1250: 6f 6e 28 74 29 20 7b 0a 20 20 76 61 72 20 6e 75  on(t) {.  var nu
1260: 6d 52 65 64 69 72 65 63 74 73 20 3d 20 30 0a 0a  mRedirects = 0..
1270: 20 20 72 65 71 75 65 73 74 28 7b 0a 20 20 20 20    request({.    
1280: 6d 65 74 68 6f 64 3a 20 27 47 45 54 27 2c 0a 20  method: 'GET',. 
1290: 20 20 20 75 72 69 3a 20 27 68 74 74 70 3a 2f 2f     uri: 'http://
12a0: 6c 6f 63 61 6c 68 6f 73 74 3a 36 37 36 37 2f 74  localhost:6767/t
12b0: 65 73 74 2f 6d 64 35 2d 73 65 73 73 27 2c 0a 20  est/md5-sess',. 
12c0: 20 20 20 61 75 74 68 3a 20 7b 0a 20 20 20 20 20     auth: {.     
12d0: 20 75 73 65 72 3a 20 27 74 65 73 74 27 2c 0a 20   user: 'test',. 
12e0: 20 20 20 20 20 70 61 73 73 3a 20 27 74 65 73 74       pass: 'test
12f0: 69 6e 67 27 2c 0a 20 20 20 20 20 20 73 65 6e 64  ing',.      send
1300: 49 6d 6d 65 64 69 61 74 65 6c 79 3a 20 66 61 6c  Immediately: fal
1310: 73 65 0a 20 20 20 20 7d 0a 20 20 7d 2c 20 66 75  se.    }.  }, fu
1320: 6e 63 74 69 6f 6e 28 65 72 72 6f 72 2c 20 72 65  nction(error, re
1330: 73 70 6f 6e 73 65 2c 20 62 6f 64 79 29 20 7b 0a  sponse, body) {.
1340: 20 20 20 20 74 2e 65 71 75 61 6c 28 65 72 72 6f      t.equal(erro
1350: 72 2c 20 6e 75 6c 6c 29 0a 20 20 20 20 74 2e 65  r, null).    t.e
1360: 71 75 61 6c 28 72 65 73 70 6f 6e 73 65 2e 73 74  qual(response.st
1370: 61 74 75 73 43 6f 64 65 2c 20 32 30 30 29 0a 20  atusCode, 200). 
1380: 20 20 20 74 2e 65 71 75 61 6c 28 6e 75 6d 52 65     t.equal(numRe
1390: 64 69 72 65 63 74 73 2c 20 31 29 0a 20 20 20 20  directs, 1).    
13a0: 74 2e 65 6e 64 28 29 0a 20 20 7d 29 2e 6f 6e 28  t.end().  }).on(
13b0: 27 72 65 64 69 72 65 63 74 27 2c 20 66 75 6e 63  'redirect', func
13c0: 74 69 6f 6e 28 29 20 7b 0a 20 20 20 20 74 2e 65  tion() {.    t.e
13d0: 71 75 61 6c 28 74 68 69 73 2e 72 65 73 70 6f 6e  qual(this.respon
13e0: 73 65 2e 73 74 61 74 75 73 43 6f 64 65 2c 20 34  se.statusCode, 4
13f0: 30 31 29 0a 20 20 20 20 6e 75 6d 52 65 64 69 72  01).    numRedir
1400: 65 63 74 73 2b 2b 0a 20 20 7d 29 0a 7d 29 0a 0a  ects++.  }).})..
1410: 74 61 70 65 28 27 77 69 74 68 6f 75 74 20 73 65  tape('without se
1420: 6e 64 49 6d 6d 65 64 69 61 74 65 6c 79 20 3d 20  ndImmediately = 
1430: 66 61 6c 73 65 27 2c 20 66 75 6e 63 74 69 6f 6e  false', function
1440: 28 74 29 20 7b 0a 20 20 76 61 72 20 6e 75 6d 52  (t) {.  var numR
1450: 65 64 69 72 65 63 74 73 20 3d 20 30 0a 0a 20 20  edirects = 0..  
1460: 2f 2f 20 49 66 20 77 65 20 64 6f 6e 27 74 20 73  // If we don't s
1470: 65 74 20 73 65 6e 64 49 6d 6d 65 64 69 61 74 65  et sendImmediate
1480: 6c 79 20 3d 20 66 61 6c 73 65 2c 20 72 65 71 75  ly = false, requ
1490: 65 73 74 20 77 69 6c 6c 20 73 65 6e 64 20 62 61  est will send ba
14a0: 73 69 63 20 61 75 74 68 0a 20 20 72 65 71 75 65  sic auth.  reque
14b0: 73 74 28 7b 0a 20 20 20 20 6d 65 74 68 6f 64 3a  st({.    method:
14c0: 20 27 47 45 54 27 2c 0a 20 20 20 20 75 72 69 3a   'GET',.    uri:
14d0: 20 27 68 74 74 70 3a 2f 2f 6c 6f 63 61 6c 68 6f   'http://localho
14e0: 73 74 3a 36 37 36 37 2f 74 65 73 74 2f 27 2c 0a  st:6767/test/',.
14f0: 20 20 20 20 61 75 74 68 3a 20 7b 0a 20 20 20 20      auth: {.    
1500: 20 20 75 73 65 72 3a 20 27 74 65 73 74 27 2c 0a    user: 'test',.
1510: 20 20 20 20 20 20 70 61 73 73 3a 20 27 74 65 73        pass: 'tes
1520: 74 69 6e 67 27 0a 20 20 20 20 7d 0a 20 20 7d 2c  ting'.    }.  },
1530: 20 66 75 6e 63 74 69 6f 6e 28 65 72 72 6f 72 2c   function(error,
1540: 20 72 65 73 70 6f 6e 73 65 2c 20 62 6f 64 79 29   response, body)
1550: 20 7b 0a 20 20 20 20 74 2e 65 71 75 61 6c 28 65   {.    t.equal(e
1560: 72 72 6f 72 2c 20 6e 75 6c 6c 29 0a 20 20 20 20  rror, null).    
1570: 74 2e 65 71 75 61 6c 28 72 65 73 70 6f 6e 73 65  t.equal(response
1580: 2e 73 74 61 74 75 73 43 6f 64 65 2c 20 34 30 31  .statusCode, 401
1590: 29 0a 20 20 20 20 74 2e 65 71 75 61 6c 28 6e 75  ).    t.equal(nu
15a0: 6d 52 65 64 69 72 65 63 74 73 2c 20 30 29 0a 20  mRedirects, 0). 
15b0: 20 20 20 74 2e 65 6e 64 28 29 0a 20 20 7d 29 2e     t.end().  }).
15c0: 6f 6e 28 27 72 65 64 69 72 65 63 74 27 2c 20 66  on('redirect', f
15d0: 75 6e 63 74 69 6f 6e 28 29 20 7b 0a 20 20 20 20  unction() {.    
15e0: 74 2e 65 71 75 61 6c 28 74 68 69 73 2e 72 65 73  t.equal(this.res
15f0: 70 6f 6e 73 65 2e 73 74 61 74 75 73 43 6f 64 65  ponse.statusCode
1600: 2c 20 34 30 31 29 0a 20 20 20 20 6e 75 6d 52 65  , 401).    numRe
1610: 64 69 72 65 63 74 73 2b 2b 0a 20 20 7d 29 0a 7d  directs++.  }).}
1620: 29 0a 0a 74 61 70 65 28 27 77 69 74 68 20 64 69  )..tape('with di
1630: 66 66 65 72 65 6e 74 20 63 72 65 64 65 6e 74 69  fferent credenti
1640: 61 6c 73 27 2c 20 66 75 6e 63 74 69 6f 6e 28 74  als', function(t
1650: 29 20 7b 0a 20 20 76 61 72 20 6e 75 6d 52 65 64  ) {.  var numRed
1660: 69 72 65 63 74 73 20 3d 20 30 0a 0a 20 20 72 65  irects = 0..  re
1670: 71 75 65 73 74 28 7b 0a 20 20 20 20 6d 65 74 68  quest({.    meth
1680: 6f 64 3a 20 27 47 45 54 27 2c 0a 20 20 20 20 75  od: 'GET',.    u
1690: 72 69 3a 20 27 68 74 74 70 3a 2f 2f 6c 6f 63 61  ri: 'http://loca
16a0: 6c 68 6f 73 74 3a 36 37 36 37 2f 64 69 72 2f 69  lhost:6767/dir/i
16b0: 6e 64 65 78 2e 68 74 6d 6c 27 2c 0a 20 20 20 20  ndex.html',.    
16c0: 61 75 74 68 3a 20 7b 0a 20 20 20 20 20 20 75 73  auth: {.      us
16d0: 65 72 3a 20 27 4d 75 66 61 73 61 27 2c 0a 20 20  er: 'Mufasa',.  
16e0: 20 20 20 20 70 61 73 73 3a 20 27 43 69 72 63 6c      pass: 'Circl
16f0: 65 4f 66 4c 69 66 65 27 2c 0a 20 20 20 20 20 20  eOfLife',.      
1700: 73 65 6e 64 49 6d 6d 65 64 69 61 74 65 6c 79 3a  sendImmediately:
1710: 20 66 61 6c 73 65 0a 20 20 20 20 7d 0a 20 20 7d   false.    }.  }
1720: 2c 20 66 75 6e 63 74 69 6f 6e 28 65 72 72 6f 72  , function(error
1730: 2c 20 72 65 73 70 6f 6e 73 65 2c 20 62 6f 64 79  , response, body
1740: 29 20 7b 0a 20 20 20 20 74 2e 65 71 75 61 6c 28  ) {.    t.equal(
1750: 65 72 72 6f 72 2c 20 6e 75 6c 6c 29 0a 20 20 20  error, null).   
1760: 20 74 2e 65 71 75 61 6c 28 72 65 73 70 6f 6e 73   t.equal(respons
1770: 65 2e 73 74 61 74 75 73 43 6f 64 65 2c 20 32 30  e.statusCode, 20
1780: 30 29 0a 20 20 20 20 74 2e 65 71 75 61 6c 28 6e  0).    t.equal(n
1790: 75 6d 52 65 64 69 72 65 63 74 73 2c 20 31 29 0a  umRedirects, 1).
17a0: 20 20 20 20 74 2e 65 6e 64 28 29 0a 20 20 7d 29      t.end().  })
17b0: 2e 6f 6e 28 27 72 65 64 69 72 65 63 74 27 2c 20  .on('redirect', 
17c0: 66 75 6e 63 74 69 6f 6e 28 29 20 7b 0a 20 20 20  function() {.   
17d0: 20 74 2e 65 71 75 61 6c 28 74 68 69 73 2e 72 65   t.equal(this.re
17e0: 73 70 6f 6e 73 65 2e 73 74 61 74 75 73 43 6f 64  sponse.statusCod
17f0: 65 2c 20 34 30 31 29 0a 20 20 20 20 6e 75 6d 52  e, 401).    numR
1800: 65 64 69 72 65 63 74 73 2b 2b 0a 20 20 7d 29 0a  edirects++.  }).
1810: 7d 29 0a 0a 74 61 70 65 28 27 63 6c 65 61 6e 75  })..tape('cleanu
1820: 70 27 2c 20 66 75 6e 63 74 69 6f 6e 28 74 29 20  p', function(t) 
1830: 7b 0a 20 20 64 69 67 65 73 74 53 65 72 76 65 72  {.  digestServer
1840: 2e 63 6c 6f 73 65 28 66 75 6e 63 74 69 6f 6e 28  .close(function(
1850: 29 20 7b 0a 20 20 20 20 74 2e 65 6e 64 28 29 0a  ) {.    t.end().
1860: 20 20 7d 29 0a 7d 29 0a                            }).}).