@wiajs/request 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/.github/ISSUE_TEMPLATE.md +56 -0
  2. package/.github/PULL_REQUEST_TEMPLATE.md +13 -0
  3. package/.github/stale.yml +19 -0
  4. package/.swcrc +57 -0
  5. package/.travis.yml +21 -0
  6. package/CHANGELOG.md +717 -0
  7. package/CONTRIBUTING.md +81 -0
  8. package/biome.json +44 -0
  9. package/codecov.yml +2 -0
  10. package/disabled.appveyor.yml +36 -0
  11. package/dist/request.cjs +1476 -0
  12. package/dist/request.mjs +1474 -0
  13. package/examples/README.md +135 -0
  14. package/gulpfile.js +71 -0
  15. package/package.json +1 -2
  16. package/release.sh +45 -0
  17. package/tests/browser/karma.conf.js +57 -0
  18. package/tests/browser/ssl/ca.crt +14 -0
  19. package/tests/browser/ssl/server.crt +14 -0
  20. package/tests/browser/ssl/server.key +15 -0
  21. package/tests/browser/start.js +37 -0
  22. package/tests/browser/test.js +34 -0
  23. package/tests/fixtures/har.json +158 -0
  24. package/tests/googledoodle.jpg +0 -0
  25. package/tests/server.js +142 -0
  26. package/tests/squid.conf +76 -0
  27. package/tests/ssl/ca/README.md +8 -0
  28. package/tests/ssl/ca/ca.cnf +20 -0
  29. package/tests/ssl/ca/ca.crl +0 -0
  30. package/tests/ssl/ca/ca.crt +17 -0
  31. package/tests/ssl/ca/ca.csr +13 -0
  32. package/tests/ssl/ca/ca.key +18 -0
  33. package/tests/ssl/ca/ca.srl +1 -0
  34. package/tests/ssl/ca/client-enc.key +30 -0
  35. package/tests/ssl/ca/client.cnf +20 -0
  36. package/tests/ssl/ca/client.crt +20 -0
  37. package/tests/ssl/ca/client.csr +18 -0
  38. package/tests/ssl/ca/client.key +27 -0
  39. package/tests/ssl/ca/gen-all-certs.sh +6 -0
  40. package/tests/ssl/ca/gen-client.sh +25 -0
  41. package/tests/ssl/ca/gen-localhost.sh +22 -0
  42. package/tests/ssl/ca/gen-server.sh +18 -0
  43. package/tests/ssl/ca/localhost.cnf +20 -0
  44. package/tests/ssl/ca/localhost.crt +20 -0
  45. package/tests/ssl/ca/localhost.csr +18 -0
  46. package/tests/ssl/ca/localhost.js +33 -0
  47. package/tests/ssl/ca/localhost.key +27 -0
  48. package/tests/ssl/ca/server.cnf +19 -0
  49. package/tests/ssl/ca/server.crt +25 -0
  50. package/tests/ssl/ca/server.csr +29 -0
  51. package/tests/ssl/ca/server.js +34 -0
  52. package/tests/ssl/ca/server.key +51 -0
  53. package/tests/ssl/npm-ca.crt +16 -0
  54. package/tests/ssl/test.crt +15 -0
  55. package/tests/ssl/test.key +15 -0
  56. package/tests/test-agent.js +102 -0
  57. package/tests/test-agentOptions.js +51 -0
  58. package/tests/test-api.js +33 -0
  59. package/tests/test-aws.js +123 -0
  60. package/tests/test-baseUrl.js +133 -0
  61. package/tests/test-basic-auth.js +221 -0
  62. package/tests/test-bearer-auth.js +187 -0
  63. package/tests/test-body.js +154 -0
  64. package/tests/test-cookies.js +130 -0
  65. package/tests/test-defaults.js +340 -0
  66. package/tests/test-digest-auth.js +232 -0
  67. package/tests/test-emptyBody.js +56 -0
  68. package/tests/test-errors.js +108 -0
  69. package/tests/test-event-forwarding.js +39 -0
  70. package/tests/test-follow-all-303.js +45 -0
  71. package/tests/test-follow-all.js +57 -0
  72. package/tests/test-form-data-error.js +85 -0
  73. package/tests/test-form-data.js +133 -0
  74. package/tests/test-form-urlencoded.js +73 -0
  75. package/tests/test-form.js +101 -0
  76. package/tests/test-gzip.js +296 -0
  77. package/tests/test-har.js +175 -0
  78. package/tests/test-hawk.js +187 -0
  79. package/tests/test-headers.js +305 -0
  80. package/tests/test-http-signature.js +110 -0
  81. package/tests/test-httpModule.js +112 -0
  82. package/tests/test-https.js +116 -0
  83. package/tests/test-isUrl.js +120 -0
  84. package/tests/test-json-request.js +117 -0
  85. package/tests/test-localAddress.js +49 -0
  86. package/tests/test-multipart-encoding.js +147 -0
  87. package/tests/test-multipart.js +129 -0
  88. package/tests/test-node-debug.js +95 -0
  89. package/tests/test-oauth.js +721 -0
  90. package/tests/test-onelineproxy.js +61 -0
  91. package/tests/test-option-reuse.js +54 -0
  92. package/tests/test-options-convenience-method.js +52 -0
  93. package/tests/test-params.js +101 -0
  94. package/tests/test-piped-redirect.js +55 -0
  95. package/tests/test-pipes.js +383 -0
  96. package/tests/test-pool.js +148 -0
  97. package/tests/test-promise.js +53 -0
  98. package/tests/test-proxy-connect.js +80 -0
  99. package/tests/test-proxy.js +304 -0
  100. package/tests/test-qs.js +135 -0
  101. package/tests/test-redirect-auth.js +131 -0
  102. package/tests/test-redirect-complex.js +93 -0
  103. package/tests/test-redirect.js +449 -0
  104. package/tests/test-rfc3986.js +106 -0
  105. package/tests/test-stream.js +36 -0
  106. package/tests/test-timeout.js +260 -0
  107. package/tests/test-timing.js +147 -0
  108. package/tests/test-toJSON.js +45 -0
  109. package/tests/test-tunnel.js +466 -0
  110. package/tests/test-unix.js +74 -0
  111. package/tests/unicycle.jpg +0 -0
  112. package/request.js +0 -1553
  113. package/src/ZlibTransform.js +0 -27
  114. package/src/caseless.js +0 -118
  115. package/src/index.js +0 -122
  116. package/src/request.js +0 -967
  117. package/src/utils.js +0 -274
@@ -0,0 +1,340 @@
1
+ 'use strict'
2
+
3
+ var server = require('./server')
4
+ var request = require('../index')
5
+ var qs = require('qs')
6
+ var tape = require('tape')
7
+
8
+ var s = server.createServer()
9
+
10
+ tape('setup', function (t) {
11
+ s.listen(0, function () {
12
+ s.on('/', function (req, res) {
13
+ res.writeHead(200, {'content-type': 'application/json'})
14
+ res.end(JSON.stringify({
15
+ method: req.method,
16
+ headers: req.headers,
17
+ qs: qs.parse(req.url.replace(/.*\?(.*)/, '$1'))
18
+ }))
19
+ })
20
+
21
+ s.on('/head', function (req, res) {
22
+ res.writeHead(200, {'x-data': JSON.stringify({method: req.method, headers: req.headers})})
23
+ res.end()
24
+ })
25
+
26
+ s.on('/set-undefined', function (req, res) {
27
+ var data = ''
28
+ req.on('data', function (d) {
29
+ data += d
30
+ })
31
+ req.on('end', function () {
32
+ res.writeHead(200, {'Content-Type': 'application/json'})
33
+ res.end(JSON.stringify({
34
+ method: req.method, headers: req.headers, data: JSON.parse(data)
35
+ }))
36
+ })
37
+ })
38
+
39
+ t.end()
40
+ })
41
+ })
42
+
43
+ tape('get(string, function)', function (t) {
44
+ request.defaults({
45
+ headers: { foo: 'bar' }
46
+ })(s.url + '/', function (e, r, b) {
47
+ b = JSON.parse(b)
48
+ t.equal(b.method, 'GET')
49
+ t.equal(b.headers.foo, 'bar')
50
+ t.end()
51
+ })
52
+ })
53
+
54
+ tape('merge headers', function (t) {
55
+ request.defaults({
56
+ headers: { foo: 'bar', merged: 'no' }
57
+ })(s.url + '/', {
58
+ headers: { merged: 'yes' }, json: true
59
+ }, function (e, r, b) {
60
+ t.equal(b.headers.foo, 'bar')
61
+ t.equal(b.headers.merged, 'yes')
62
+ t.end()
63
+ })
64
+ })
65
+
66
+ tape('deep extend', function (t) {
67
+ request.defaults({
68
+ headers: { a: 1, b: 2 },
69
+ qs: { a: 1, b: 2 }
70
+ })(s.url + '/', {
71
+ headers: { b: 3, c: 4 },
72
+ qs: { b: 3, c: 4 },
73
+ json: true
74
+ }, function (e, r, b) {
75
+ delete b.headers.host
76
+ delete b.headers.accept
77
+ delete b.headers.connection
78
+ t.deepEqual(b.headers, { a: '1', b: '3', c: '4' })
79
+ t.deepEqual(b.qs, { a: '1', b: '3', c: '4' })
80
+ t.end()
81
+ })
82
+ })
83
+
84
+ tape('default undefined header', function (t) {
85
+ request.defaults({
86
+ headers: { foo: 'bar', test: undefined }, json: true
87
+ })(s.url + '/', function (e, r, b) {
88
+ t.equal(b.method, 'GET')
89
+ t.equal(b.headers.foo, 'bar')
90
+ t.equal(b.headers.test, undefined)
91
+ t.end()
92
+ })
93
+ })
94
+
95
+ tape('post(string, object, function)', function (t) {
96
+ request.defaults({
97
+ headers: { foo: 'bar' }
98
+ }).post(s.url + '/', { json: true }, function (e, r, b) {
99
+ t.equal(b.method, 'POST')
100
+ t.equal(b.headers.foo, 'bar')
101
+ t.equal(b.headers['content-type'], undefined)
102
+ t.end()
103
+ })
104
+ })
105
+
106
+ tape('patch(string, object, function)', function (t) {
107
+ request.defaults({
108
+ headers: { foo: 'bar' }
109
+ }).patch(s.url + '/', { json: true }, function (e, r, b) {
110
+ t.equal(b.method, 'PATCH')
111
+ t.equal(b.headers.foo, 'bar')
112
+ t.equal(b.headers['content-type'], undefined)
113
+ t.end()
114
+ })
115
+ })
116
+
117
+ tape('post(string, object, function) with body', function (t) {
118
+ request.defaults({
119
+ headers: { foo: 'bar' }
120
+ }).post(s.url + '/', {
121
+ json: true,
122
+ body: { bar: 'baz' }
123
+ }, function (e, r, b) {
124
+ t.equal(b.method, 'POST')
125
+ t.equal(b.headers.foo, 'bar')
126
+ t.equal(b.headers['content-type'], 'application/json')
127
+ t.end()
128
+ })
129
+ })
130
+
131
+ tape('del(string, function)', function (t) {
132
+ request.defaults({
133
+ headers: {foo: 'bar'},
134
+ json: true
135
+ }).del(s.url + '/', function (e, r, b) {
136
+ t.equal(b.method, 'DELETE')
137
+ t.equal(b.headers.foo, 'bar')
138
+ t.end()
139
+ })
140
+ })
141
+
142
+ tape('delete(string, function)', function (t) {
143
+ request.defaults({
144
+ headers: {foo: 'bar'},
145
+ json: true
146
+ }).delete(s.url + '/', function (e, r, b) {
147
+ t.equal(b.method, 'DELETE')
148
+ t.equal(b.headers.foo, 'bar')
149
+ t.end()
150
+ })
151
+ })
152
+
153
+ tape('head(object, function)', function (t) {
154
+ request.defaults({
155
+ headers: { foo: 'bar' }
156
+ }).head({ uri: s.url + '/head' }, function (e, r, b) {
157
+ b = JSON.parse(r.headers['x-data'])
158
+ t.equal(b.method, 'HEAD')
159
+ t.equal(b.headers.foo, 'bar')
160
+ t.end()
161
+ })
162
+ })
163
+
164
+ tape('recursive defaults', function (t) {
165
+ t.plan(11)
166
+
167
+ var defaultsOne = request.defaults({ headers: { foo: 'bar1' } })
168
+ var defaultsTwo = defaultsOne.defaults({ headers: { baz: 'bar2' } })
169
+ var defaultsThree = defaultsTwo.defaults({}, function (options, callback) {
170
+ options.headers = {
171
+ foo: 'bar3'
172
+ }
173
+ defaultsTwo(options, callback)
174
+ })
175
+
176
+ defaultsOne(s.url + '/', {json: true}, function (e, r, b) {
177
+ t.equal(b.method, 'GET')
178
+ t.equal(b.headers.foo, 'bar1')
179
+ })
180
+
181
+ defaultsTwo(s.url + '/', {json: true}, function (e, r, b) {
182
+ t.equal(b.method, 'GET')
183
+ t.equal(b.headers.foo, 'bar1')
184
+ t.equal(b.headers.baz, 'bar2')
185
+ })
186
+
187
+ // requester function on recursive defaults
188
+ defaultsThree(s.url + '/', {json: true}, function (e, r, b) {
189
+ t.equal(b.method, 'GET')
190
+ t.equal(b.headers.foo, 'bar3')
191
+ t.equal(b.headers.baz, 'bar2')
192
+ })
193
+
194
+ defaultsTwo.get(s.url + '/', {json: true}, function (e, r, b) {
195
+ t.equal(b.method, 'GET')
196
+ t.equal(b.headers.foo, 'bar1')
197
+ t.equal(b.headers.baz, 'bar2')
198
+ })
199
+ })
200
+
201
+ tape('recursive defaults requester', function (t) {
202
+ t.plan(5)
203
+
204
+ var defaultsOne = request.defaults({}, function (options, callback) {
205
+ var headers = options.headers || {}
206
+ headers.foo = 'bar1'
207
+ options.headers = headers
208
+
209
+ request(options, callback)
210
+ })
211
+
212
+ var defaultsTwo = defaultsOne.defaults({}, function (options, callback) {
213
+ var headers = options.headers || {}
214
+ headers.baz = 'bar2'
215
+ options.headers = headers
216
+
217
+ defaultsOne(options, callback)
218
+ })
219
+
220
+ defaultsOne.get(s.url + '/', {json: true}, function (e, r, b) {
221
+ t.equal(b.method, 'GET')
222
+ t.equal(b.headers.foo, 'bar1')
223
+ })
224
+
225
+ defaultsTwo.get(s.url + '/', {json: true}, function (e, r, b) {
226
+ t.equal(b.method, 'GET')
227
+ t.equal(b.headers.foo, 'bar1')
228
+ t.equal(b.headers.baz, 'bar2')
229
+ })
230
+ })
231
+
232
+ tape('test custom request handler function', function (t) {
233
+ t.plan(3)
234
+
235
+ var requestWithCustomHandler = request.defaults({
236
+ headers: { foo: 'bar' },
237
+ body: 'TESTING!'
238
+ }, function (uri, options, callback) {
239
+ var params = request.initParams(uri, options, callback)
240
+ params.headers.x = 'y'
241
+ return request(params.uri, params, params.callback)
242
+ })
243
+
244
+ t.throws(function () {
245
+ requestWithCustomHandler.head(s.url + '/', function (e, r, b) {
246
+ throw new Error('We should never get here')
247
+ })
248
+ }, /HTTP HEAD requests MUST NOT include a request body/)
249
+
250
+ requestWithCustomHandler.get(s.url + '/', function (e, r, b) {
251
+ b = JSON.parse(b)
252
+ t.equal(b.headers.foo, 'bar')
253
+ t.equal(b.headers.x, 'y')
254
+ })
255
+ })
256
+
257
+ tape('test custom request handler function without options', function (t) {
258
+ t.plan(2)
259
+
260
+ var customHandlerWithoutOptions = request.defaults(function (uri, options, callback) {
261
+ var params = request.initParams(uri, options, callback)
262
+ var headers = params.headers || {}
263
+ headers.x = 'y'
264
+ headers.foo = 'bar'
265
+ params.headers = headers
266
+ return request(params.uri, params, params.callback)
267
+ })
268
+
269
+ customHandlerWithoutOptions.get(s.url + '/', function (e, r, b) {
270
+ b = JSON.parse(b)
271
+ t.equal(b.headers.foo, 'bar')
272
+ t.equal(b.headers.x, 'y')
273
+ })
274
+ })
275
+
276
+ tape('test only setting undefined properties', function (t) {
277
+ request.defaults({
278
+ method: 'post',
279
+ json: true,
280
+ headers: { 'x-foo': 'bar' }
281
+ })({
282
+ uri: s.url + '/set-undefined',
283
+ json: {foo: 'bar'},
284
+ headers: {'x-foo': 'baz'}
285
+ }, function (e, r, b) {
286
+ t.equal(b.method, 'POST')
287
+ t.equal(b.headers['content-type'], 'application/json')
288
+ t.equal(b.headers['x-foo'], 'baz')
289
+ t.deepEqual(b.data, { foo: 'bar' })
290
+ t.end()
291
+ })
292
+ })
293
+
294
+ tape('test only function', function (t) {
295
+ var post = request.post
296
+ t.doesNotThrow(function () {
297
+ post(s.url + '/', function (e, r, b) {
298
+ t.equal(r.statusCode, 200)
299
+ t.end()
300
+ })
301
+ })
302
+ })
303
+
304
+ tape('invoke defaults', function (t) {
305
+ var d = request.defaults({
306
+ uri: s.url + '/',
307
+ headers: { foo: 'bar' }
308
+ })
309
+ d({json: true}, function (e, r, b) {
310
+ t.equal(b.method, 'GET')
311
+ t.equal(b.headers.foo, 'bar')
312
+ t.end()
313
+ })
314
+ })
315
+
316
+ tape('invoke convenience method from defaults', function (t) {
317
+ var d = request.defaults({
318
+ uri: s.url + '/',
319
+ headers: { foo: 'bar' }
320
+ })
321
+ d.get({json: true}, function (e, r, b) {
322
+ t.equal(b.method, 'GET')
323
+ t.equal(b.headers.foo, 'bar')
324
+ t.end()
325
+ })
326
+ })
327
+
328
+ tape('defaults without options', function (t) {
329
+ var d = request.defaults()
330
+ d.get(s.url + '/', {json: true}, function (e, r, b) {
331
+ t.equal(r.statusCode, 200)
332
+ t.end()
333
+ })
334
+ })
335
+
336
+ tape('cleanup', function (t) {
337
+ s.close(function () {
338
+ t.end()
339
+ })
340
+ })
@@ -0,0 +1,232 @@
1
+ 'use strict'
2
+
3
+ var http = require('http')
4
+ var request = require('../index')
5
+ var tape = require('tape')
6
+ var crypto = require('crypto')
7
+
8
+ function makeHeader () {
9
+ return [].join.call(arguments, ', ')
10
+ }
11
+
12
+ function makeHeaderRegex () {
13
+ return new RegExp('^' + makeHeader.apply(null, arguments) + '$')
14
+ }
15
+
16
+ function md5 (str) {
17
+ return crypto.createHash('md5').update(str).digest('hex')
18
+ }
19
+
20
+ var digestServer = http.createServer(function (req, res) {
21
+ var ok,
22
+ testHeader
23
+
24
+ if (req.url === '/test/') {
25
+ if (req.headers.authorization) {
26
+ testHeader = makeHeaderRegex(
27
+ 'Digest username="test"',
28
+ 'realm="Private"',
29
+ 'nonce="WpcHS2/TBAA=dffcc0dbd5f96d49a5477166649b7c0ae3866a93"',
30
+ 'uri="/test/"',
31
+ 'qop=auth',
32
+ 'response="[a-f0-9]{32}"',
33
+ 'nc=00000001',
34
+ 'cnonce="[a-f0-9]{32}"',
35
+ 'algorithm=MD5',
36
+ 'opaque="5ccc069c403ebaf9f0171e9517f40e41"'
37
+ )
38
+ if (testHeader.test(req.headers.authorization)) {
39
+ ok = true
40
+ } else {
41
+ // Bad auth header, don't send back WWW-Authenticate header
42
+ ok = false
43
+ }
44
+ } else {
45
+ // No auth header, send back WWW-Authenticate header
46
+ ok = false
47
+ res.setHeader('www-authenticate', makeHeader(
48
+ 'Digest realm="Private"',
49
+ 'nonce="WpcHS2/TBAA=dffcc0dbd5f96d49a5477166649b7c0ae3866a93"',
50
+ 'algorithm=MD5',
51
+ 'qop="auth"',
52
+ 'opaque="5ccc069c403ebaf9f0171e9517f40e41"'
53
+ ))
54
+ }
55
+ } else if (req.url === '/test/md5-sess') { // RFC 2716 MD5-sess w/ qop=auth
56
+ var user = 'test'
57
+ var realm = 'Private'
58
+ var pass = 'testing'
59
+ var nonce = 'WpcHS2/TBAA=dffcc0dbd5f96d49a5477166649b7c0ae3866a93'
60
+ var nonceCount = '00000001'
61
+ var qop = 'auth'
62
+ var algorithm = 'MD5-sess'
63
+ if (req.headers.authorization) {
64
+ // HA1=MD5(MD5(username:realm:password):nonce:cnonce)
65
+ // HA2=MD5(method:digestURI)
66
+ // response=MD5(HA1:nonce:nonceCount:clientNonce:qop:HA2)
67
+
68
+ var cnonce = /cnonce="(.*)"/.exec(req.headers.authorization)[1]
69
+ var ha1 = md5(md5(user + ':' + realm + ':' + pass) + ':' + nonce + ':' + cnonce)
70
+ var ha2 = md5('GET:/test/md5-sess')
71
+ var response = md5(ha1 + ':' + nonce + ':' + nonceCount + ':' + cnonce + ':' + qop + ':' + ha2)
72
+
73
+ testHeader = makeHeaderRegex(
74
+ 'Digest username="' + user + '"',
75
+ 'realm="' + realm + '"',
76
+ 'nonce="' + nonce + '"',
77
+ 'uri="/test/md5-sess"',
78
+ 'qop=' + qop,
79
+ 'response="' + response + '"',
80
+ 'nc=' + nonceCount,
81
+ 'cnonce="' + cnonce + '"',
82
+ 'algorithm=' + algorithm
83
+ )
84
+
85
+ ok = testHeader.test(req.headers.authorization)
86
+ } else {
87
+ // No auth header, send back WWW-Authenticate header
88
+ ok = false
89
+ res.setHeader('www-authenticate', makeHeader(
90
+ 'Digest realm="' + realm + '"',
91
+ 'nonce="' + nonce + '"',
92
+ 'algorithm=' + algorithm,
93
+ 'qop="' + qop + '"'
94
+ ))
95
+ }
96
+ } else if (req.url === '/dir/index.html') {
97
+ // RFC2069-compatible mode
98
+ // check: http://www.rfc-editor.org/errata_search.php?rfc=2069
99
+ if (req.headers.authorization) {
100
+ testHeader = makeHeaderRegex(
101
+ 'Digest username="Mufasa"',
102
+ 'realm="testrealm@host.com"',
103
+ 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"',
104
+ 'uri="/dir/index.html"',
105
+ 'response="[a-f0-9]{32}"',
106
+ 'opaque="5ccc069c403ebaf9f0171e9517f40e41"'
107
+ )
108
+ if (testHeader.test(req.headers.authorization)) {
109
+ ok = true
110
+ } else {
111
+ // Bad auth header, don't send back WWW-Authenticate header
112
+ ok = false
113
+ }
114
+ } else {
115
+ // No auth header, send back WWW-Authenticate header
116
+ ok = false
117
+ res.setHeader('www-authenticate', makeHeader(
118
+ 'Digest realm="testrealm@host.com"',
119
+ 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"',
120
+ 'opaque="5ccc069c403ebaf9f0171e9517f40e41"'
121
+ ))
122
+ }
123
+ }
124
+
125
+ if (ok) {
126
+ res.end('ok')
127
+ } else {
128
+ res.statusCode = 401
129
+ res.end('401')
130
+ }
131
+ })
132
+
133
+ tape('setup', function (t) {
134
+ digestServer.listen(0, function () {
135
+ digestServer.url = 'http://localhost:' + this.address().port
136
+ t.end()
137
+ })
138
+ })
139
+
140
+ tape('with sendImmediately = false', function (t) {
141
+ var numRedirects = 0
142
+
143
+ request({
144
+ method: 'GET',
145
+ uri: digestServer.url + '/test/',
146
+ auth: {
147
+ user: 'test',
148
+ pass: 'testing',
149
+ sendImmediately: false
150
+ }
151
+ }, function (error, response, body) {
152
+ t.equal(error, null)
153
+ t.equal(response.statusCode, 200)
154
+ t.equal(numRedirects, 1)
155
+ t.end()
156
+ }).on('redirect', function () {
157
+ t.equal(this.response.statusCode, 401)
158
+ numRedirects++
159
+ })
160
+ })
161
+
162
+ tape('with MD5-sess algorithm', function (t) {
163
+ var numRedirects = 0
164
+
165
+ request({
166
+ method: 'GET',
167
+ uri: digestServer.url + '/test/md5-sess',
168
+ auth: {
169
+ user: 'test',
170
+ pass: 'testing',
171
+ sendImmediately: false
172
+ }
173
+ }, function (error, response, body) {
174
+ t.equal(error, null)
175
+ t.equal(response.statusCode, 200)
176
+ t.equal(numRedirects, 1)
177
+ t.end()
178
+ }).on('redirect', function () {
179
+ t.equal(this.response.statusCode, 401)
180
+ numRedirects++
181
+ })
182
+ })
183
+
184
+ tape('without sendImmediately = false', function (t) {
185
+ var numRedirects = 0
186
+
187
+ // If we don't set sendImmediately = false, request will send basic auth
188
+ request({
189
+ method: 'GET',
190
+ uri: digestServer.url + '/test/',
191
+ auth: {
192
+ user: 'test',
193
+ pass: 'testing'
194
+ }
195
+ }, function (error, response, body) {
196
+ t.equal(error, null)
197
+ t.equal(response.statusCode, 401)
198
+ t.equal(numRedirects, 0)
199
+ t.end()
200
+ }).on('redirect', function () {
201
+ t.equal(this.response.statusCode, 401)
202
+ numRedirects++
203
+ })
204
+ })
205
+
206
+ tape('with different credentials', function (t) {
207
+ var numRedirects = 0
208
+
209
+ request({
210
+ method: 'GET',
211
+ uri: digestServer.url + '/dir/index.html',
212
+ auth: {
213
+ user: 'Mufasa',
214
+ pass: 'CircleOfLife',
215
+ sendImmediately: false
216
+ }
217
+ }, function (error, response, body) {
218
+ t.equal(error, null)
219
+ t.equal(response.statusCode, 200)
220
+ t.equal(numRedirects, 1)
221
+ t.end()
222
+ }).on('redirect', function () {
223
+ t.equal(this.response.statusCode, 401)
224
+ numRedirects++
225
+ })
226
+ })
227
+
228
+ tape('cleanup', function (t) {
229
+ digestServer.close(function () {
230
+ t.end()
231
+ })
232
+ })
@@ -0,0 +1,56 @@
1
+ 'use strict'
2
+
3
+ var request = require('../index')
4
+ var http = require('http')
5
+ var tape = require('tape')
6
+
7
+ var s = http.createServer(function (req, resp) {
8
+ resp.statusCode = 200
9
+ resp.end('')
10
+ })
11
+
12
+ tape('setup', function (t) {
13
+ s.listen(0, function () {
14
+ s.url = 'http://localhost:' + this.address().port
15
+ t.end()
16
+ })
17
+ })
18
+
19
+ tape('empty body with encoding', function (t) {
20
+ request(s.url, function (err, res, body) {
21
+ t.equal(err, null)
22
+ t.equal(res.statusCode, 200)
23
+ t.equal(body, '')
24
+ t.end()
25
+ })
26
+ })
27
+
28
+ tape('empty body without encoding', function (t) {
29
+ request({
30
+ url: s.url,
31
+ encoding: null
32
+ }, function (err, res, body) {
33
+ t.equal(err, null)
34
+ t.equal(res.statusCode, 200)
35
+ t.same(body, Buffer.alloc(0))
36
+ t.end()
37
+ })
38
+ })
39
+
40
+ tape('empty JSON body', function (t) {
41
+ request({
42
+ url: s.url,
43
+ json: {}
44
+ }, function (err, res, body) {
45
+ t.equal(err, null)
46
+ t.equal(res.statusCode, 200)
47
+ t.equal(body, undefined)
48
+ t.end()
49
+ })
50
+ })
51
+
52
+ tape('cleanup', function (t) {
53
+ s.close(function () {
54
+ t.end()
55
+ })
56
+ })