@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,305 @@
1
+ 'use strict'
2
+
3
+ var server = require('./server')
4
+ var request = require('../index')
5
+ var util = require('util')
6
+ var tape = require('tape')
7
+ var url = require('url')
8
+ var os = require('os')
9
+
10
+ var interfaces = os.networkInterfaces()
11
+ var loopbackKeyTest = os.platform() === 'win32' ? /Loopback Pseudo-Interface/ : /lo/
12
+ var hasIPv6interface = Object.keys(interfaces).some(function (name) {
13
+ return loopbackKeyTest.test(name) && interfaces[name].some(function (info) {
14
+ return info.family === 'IPv6'
15
+ })
16
+ })
17
+
18
+ var s = server.createServer()
19
+
20
+ s.on('/redirect/from', function (req, res) {
21
+ res.writeHead(301, {
22
+ location: '/redirect/to'
23
+ })
24
+ res.end()
25
+ })
26
+
27
+ s.on('/redirect/to', function (req, res) {
28
+ res.end('ok')
29
+ })
30
+
31
+ s.on('/headers.json', function (req, res) {
32
+ res.writeHead(200, {
33
+ 'Content-Type': 'application/json'
34
+ })
35
+
36
+ res.end(JSON.stringify(req.headers))
37
+ })
38
+
39
+ function runTest (name, path, requestObj, serverAssertFn) {
40
+ tape(name, function (t) {
41
+ s.on('/' + path, function (req, res) {
42
+ serverAssertFn(t, req, res)
43
+ res.writeHead(200)
44
+ res.end()
45
+ })
46
+ requestObj.url = s.url + '/' + path
47
+ request(requestObj, function (err, res, body) {
48
+ t.equal(err, null)
49
+ t.equal(res.statusCode, 200)
50
+ t.end()
51
+ })
52
+ })
53
+ }
54
+
55
+ function addTests () {
56
+ runTest(
57
+ '#125: headers.cookie with no cookie jar',
58
+ 'no-jar',
59
+ {headers: {cookie: 'foo=bar'}},
60
+ function (t, req, res) {
61
+ t.equal(req.headers.cookie, 'foo=bar')
62
+ })
63
+
64
+ var jar = request.jar()
65
+ jar.setCookie('quux=baz', s.url)
66
+ runTest(
67
+ '#125: headers.cookie + cookie jar',
68
+ 'header-and-jar',
69
+ {jar: jar, headers: {cookie: 'foo=bar'}},
70
+ function (t, req, res) {
71
+ t.equal(req.headers.cookie, 'foo=bar; quux=baz')
72
+ })
73
+
74
+ var jar2 = request.jar()
75
+ jar2.setCookie('quux=baz; Domain=foo.bar.com', s.url, {ignoreError: true})
76
+ runTest(
77
+ '#794: ignore cookie parsing and domain errors',
78
+ 'ignore-errors',
79
+ {jar: jar2, headers: {cookie: 'foo=bar'}},
80
+ function (t, req, res) {
81
+ t.equal(req.headers.cookie, 'foo=bar')
82
+ })
83
+
84
+ runTest(
85
+ '#784: override content-type when json is used',
86
+ 'json',
87
+ {
88
+ json: true,
89
+ method: 'POST',
90
+ headers: { 'content-type': 'application/json; charset=UTF-8' },
91
+ body: { hello: 'my friend' }},
92
+ function (t, req, res) {
93
+ t.equal(req.headers['content-type'], 'application/json; charset=UTF-8')
94
+ }
95
+ )
96
+
97
+ runTest(
98
+ 'neither headers.cookie nor a cookie jar is specified',
99
+ 'no-cookie',
100
+ {},
101
+ function (t, req, res) {
102
+ t.equal(req.headers.cookie, undefined)
103
+ })
104
+ }
105
+
106
+ tape('setup', function (t) {
107
+ s.listen(0, function () {
108
+ addTests()
109
+ tape('cleanup', function (t) {
110
+ s.close(function () {
111
+ t.end()
112
+ })
113
+ })
114
+ t.end()
115
+ })
116
+ })
117
+
118
+ tape('upper-case Host header and redirect', function (t) {
119
+ // Horrible hack to observe the raw data coming to the server (before Node
120
+ // core lower-cases the headers)
121
+ var rawData = ''
122
+
123
+ s.on('connection', function (socket) {
124
+ if (socket.ondata) {
125
+ var ondata = socket.ondata
126
+ }
127
+ function handledata (d, start, end) {
128
+ if (ondata) {
129
+ rawData += d.slice(start, end).toString()
130
+ return ondata.apply(this, arguments)
131
+ } else {
132
+ rawData += d
133
+ }
134
+ }
135
+ socket.on('data', handledata)
136
+ socket.ondata = handledata
137
+ })
138
+
139
+ function checkHostHeader (host) {
140
+ t.ok(
141
+ new RegExp('^Host: ' + host + '$', 'm').test(rawData),
142
+ util.format(
143
+ 'Expected "Host: %s" in data "%s"',
144
+ host, rawData.trim().replace(/\r?\n/g, '\\n')))
145
+ rawData = ''
146
+ }
147
+
148
+ var redirects = 0
149
+ request({
150
+ url: s.url + '/redirect/from',
151
+ headers: { Host: '127.0.0.1' }
152
+ }, function (err, res, body) {
153
+ t.equal(err, null)
154
+ t.equal(res.statusCode, 200)
155
+ t.equal(body, 'ok')
156
+ t.equal(redirects, 1)
157
+ // XXX should the host header change like this after a redirect?
158
+ checkHostHeader('localhost:' + s.port)
159
+ t.end()
160
+ }).on('redirect', function () {
161
+ redirects++
162
+ t.equal(this.uri.href, s.url + '/redirect/to')
163
+ checkHostHeader('127.0.0.1')
164
+ })
165
+ })
166
+
167
+ tape('undefined headers', function (t) {
168
+ request({
169
+ url: s.url + '/headers.json',
170
+ headers: {
171
+ 'X-TEST-1': 'test1',
172
+ 'X-TEST-2': undefined
173
+ },
174
+ json: true
175
+ }, function (err, res, body) {
176
+ t.equal(err, null)
177
+ t.equal(body['x-test-1'], 'test1')
178
+ t.equal(typeof body['x-test-2'], 'undefined')
179
+ t.end()
180
+ })
181
+ })
182
+
183
+ tape('preserve port in host header if non-standard port', function (t) {
184
+ var r = request({
185
+ url: s.url + '/headers.json'
186
+ }, function (err, res, body) {
187
+ t.equal(err, null)
188
+ t.equal(r.originalHost, 'localhost:' + s.port)
189
+ t.end()
190
+ })
191
+ })
192
+
193
+ tape('strip port in host header if explicit standard port (:80) & protocol (HTTP)', function (t) {
194
+ var r = request({
195
+ url: 'http://localhost:80/headers.json'
196
+ }, function (_err, res, body) {
197
+ t.equal(r.req.socket._host, 'localhost')
198
+ t.end()
199
+ })
200
+ })
201
+
202
+ tape('strip port in host header if explicit standard port (:443) & protocol (HTTPS)', function (t) {
203
+ var r = request({
204
+ url: 'https://localhost:443/headers.json'
205
+ }, function (_err, res, body) {
206
+ t.equal(r.req.socket._host, 'localhost')
207
+ t.end()
208
+ })
209
+ })
210
+
211
+ tape('strip port in host header if implicit standard port & protocol (HTTP)', function (t) {
212
+ var r = request({
213
+ url: 'http://localhost/headers.json'
214
+ }, function (_err, res, body) {
215
+ t.equal(r.req.socket._host, 'localhost')
216
+ t.end()
217
+ })
218
+ })
219
+
220
+ tape('strip port in host header if implicit standard port & protocol (HTTPS)', function (t) {
221
+ var r = request({
222
+ url: 'https://localhost/headers.json'
223
+ }, function (_err, res, body) {
224
+ t.equal(r.req.socket._host, 'localhost')
225
+ t.end()
226
+ })
227
+ })
228
+
229
+ var isExpectedHeaderCharacterError = function (headerName, err) {
230
+ return err.message === 'The header content contains invalid characters' ||
231
+ err.message === ('Invalid character in header content ["' + headerName + '"]')
232
+ }
233
+
234
+ tape('catch invalid characters error - GET', function (t) {
235
+ request({
236
+ url: s.url + '/headers.json',
237
+ headers: {
238
+ 'test': 'אבגד'
239
+ }
240
+ }, function (err, res, body) {
241
+ t.true(isExpectedHeaderCharacterError('test', err))
242
+ })
243
+ .on('error', function (err) {
244
+ t.true(isExpectedHeaderCharacterError('test', err))
245
+ t.end()
246
+ })
247
+ })
248
+
249
+ tape('catch invalid characters error - POST', function (t) {
250
+ request({
251
+ method: 'POST',
252
+ url: s.url + '/headers.json',
253
+ headers: {
254
+ 'test': 'אבגד'
255
+ },
256
+ body: 'beep'
257
+ }, function (err, res, body) {
258
+ t.true(isExpectedHeaderCharacterError('test', err))
259
+ })
260
+ .on('error', function (err) {
261
+ t.true(isExpectedHeaderCharacterError('test', err))
262
+ t.end()
263
+ })
264
+ })
265
+
266
+ if (hasIPv6interface) {
267
+ tape('IPv6 Host header', function (t) {
268
+ // Horrible hack to observe the raw data coming to the server
269
+ var rawData = ''
270
+
271
+ s.on('connection', function (socket) {
272
+ if (socket.ondata) {
273
+ var ondata = socket.ondata
274
+ }
275
+ function handledata (d, start, end) {
276
+ if (ondata) {
277
+ rawData += d.slice(start, end).toString()
278
+ return ondata.apply(this, arguments)
279
+ } else {
280
+ rawData += d
281
+ }
282
+ }
283
+ socket.on('data', handledata)
284
+ socket.ondata = handledata
285
+ })
286
+
287
+ function checkHostHeader (host) {
288
+ t.ok(
289
+ new RegExp('^Host: ' + host + '$', 'im').test(rawData),
290
+ util.format(
291
+ 'Expected "Host: %s" in data "%s"',
292
+ host, rawData.trim().replace(/\r?\n/g, '\\n')))
293
+ rawData = ''
294
+ }
295
+
296
+ request({
297
+ url: s.url.replace(url.parse(s.url).hostname, '[::1]') + '/headers.json'
298
+ }, function (err, res, body) {
299
+ t.equal(err, null)
300
+ t.equal(res.statusCode, 200)
301
+ checkHostHeader('\\[::1\\]:' + s.port)
302
+ t.end()
303
+ })
304
+ })
305
+ }
@@ -0,0 +1,110 @@
1
+ 'use strict'
2
+
3
+ var http = require('http')
4
+ var request = require('../index')
5
+ var httpSignature = require('http-signature')
6
+ var tape = require('tape')
7
+
8
+ var privateKeyPEMs = {}
9
+
10
+ privateKeyPEMs['key-1'] =
11
+ '-----BEGIN RSA PRIVATE KEY-----\n' +
12
+ 'MIIEpAIBAAKCAQEAzWSJl+Z9Bqv00FVL5N3+JCUoqmQPjIlya1BbeqQroNQ5yG1i\n' +
13
+ 'VbYTTnMRa1zQtR6r2fNvWeg94DvxivxIG9diDMnrzijAnYlTLOl84CK2vOxkj5b6\n' +
14
+ '8zrLH9b/Gd6NOHsywo8IjvXvCeTfca5WUHcuVi2lT9VjygFs1ILG4RyeX1BXUumu\n' +
15
+ 'Y8fzmposxLYdMxCqUTzAn0u9Saq2H2OVj5u114wS7OQPigu6G99dpn/iPHa3zBm8\n' +
16
+ '7baBWDbqZWRW0BP3K6eqq8sut1+NLhNW8ADPTdnO/SO+kvXy7fqd8atSn+HlQcx6\n' +
17
+ 'tW42dhXf3E9uE7K78eZtW0KvfyNGAjsI1Fft2QIDAQABAoIBAG1exe3/LEBrPLfb\n' +
18
+ 'U8iRdY0lxFvHYIhDgIwohC3wUdMYb5SMurpNdEZn+7Sh/fkUVgp/GKJViu1mvh52\n' +
19
+ 'bKd2r52DwG9NQBQjVgkqY/auRYSglIPpr8PpYNSZlcneunCDGeqEY9hMmXc5Ssqs\n' +
20
+ 'PQYoEKKPN+IlDTg6PguDgAfLR4IUvt9KXVvmB/SSgV9tSeTy35LECt1Lq3ozbUgu\n' +
21
+ '30HZI3U6/7H+X22Pxxf8vzBtzkg5rRCLgv+OeNPo16xMnqbutt4TeqEkxRv5rtOo\n' +
22
+ '/A1i9khBeki0OJAFJsE82qnaSZodaRsxic59VnN8sWBwEKAt87tEu5A3K3j4XSDU\n' +
23
+ '/avZxAECgYEA+pS3DvpiQLtHlaO3nAH6MxHRrREOARXWRDe5nUQuUNpS1xq9wte6\n' +
24
+ 'DkFtba0UCvDLic08xvReTCbo9kH0y6zEy3zMpZuJlKbcWCkZf4S5miYPI0RTZtF8\n' +
25
+ 'yps6hWqzYFSiO9hMYws9k4OJLxX0x3sLK7iNZ32ujcSrkPBSiBr0gxkCgYEA0dWl\n' +
26
+ '637K41AJ/zy0FP0syq+r4eIkfqv+/t6y2aQVUBvxJYrj9ci6XHBqoxpDV8lufVYj\n' +
27
+ 'fUAfeI9/MZaWvQJRbnYLre0I6PJfLuCBIL5eflO77BGso165AF7QJZ+fwtgKv3zv\n' +
28
+ 'ZX75eudCSS/cFo0po9hlbcLMT4B82zEkgT8E2MECgYEAnz+3/wrdOmpLGiyL2dff\n' +
29
+ '3GjsqmJ2VfY8z+niSrI0BSpbD11tT9Ct67VlCBjA7hsOH6uRfpd6/kaUMzzDiFVq\n' +
30
+ 'VDAiFvV8QD6zNkwYalQ9aFvbrvwTTPrBpjl0vamMCiJ/YC0cjq1sGr2zh3sar1Ph\n' +
31
+ 'S43kP+s97dcZeelhaiJHVrECgYEAsx61q/loJ/LDFeYzs1cLTVn4V7I7hQY9fkOM\n' +
32
+ 'WM0AhInVqD6PqdfXfeFYpjJdGisQ7l0BnoGGW9vir+nkcyPvb2PFRIr6+B8tsU5j\n' +
33
+ '7BeVgjDoUfQkcrEBK5fEBtnj/ud9BUkY8oMZZBjVNLRuI7IMwZiPvMp0rcj4zAN/\n' +
34
+ 'LfUlpgECgYArBvFcBxSkNAzR3Rtteud1YDboSKluRM37Ey5plrn4BS0DD0jm++aD\n' +
35
+ '0pG2Hsik000hibw92lCkzvvBVAqF8BuAcnPlAeYfsOaa97PGEjSKEN5bJVWZ9/om\n' +
36
+ '9FV1axotRN2XWlwrhixZLEaagkREXhgQc540FS5O8IaI2Vpa80Atzg==\n' +
37
+ '-----END RSA PRIVATE KEY-----'
38
+
39
+ var publicKeyPEMs = {}
40
+
41
+ publicKeyPEMs['key-1'] =
42
+ '-----BEGIN PUBLIC KEY-----\n' +
43
+ 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzWSJl+Z9Bqv00FVL5N3+\n' +
44
+ 'JCUoqmQPjIlya1BbeqQroNQ5yG1iVbYTTnMRa1zQtR6r2fNvWeg94DvxivxIG9di\n' +
45
+ 'DMnrzijAnYlTLOl84CK2vOxkj5b68zrLH9b/Gd6NOHsywo8IjvXvCeTfca5WUHcu\n' +
46
+ 'Vi2lT9VjygFs1ILG4RyeX1BXUumuY8fzmposxLYdMxCqUTzAn0u9Saq2H2OVj5u1\n' +
47
+ '14wS7OQPigu6G99dpn/iPHa3zBm87baBWDbqZWRW0BP3K6eqq8sut1+NLhNW8ADP\n' +
48
+ 'TdnO/SO+kvXy7fqd8atSn+HlQcx6tW42dhXf3E9uE7K78eZtW0KvfyNGAjsI1Fft\n' +
49
+ '2QIDAQAB\n' +
50
+ '-----END PUBLIC KEY-----'
51
+
52
+ publicKeyPEMs['key-2'] =
53
+ '-----BEGIN PUBLIC KEY-----\n' +
54
+ 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqp04VVr9OThli9b35Omz\n' +
55
+ 'VqSfWbsoQuRrgyWsrNRn3XkFmbWw4FzZwQ42OgGMzQ84Ta4d9zGKKQyFriTiPjPf\n' +
56
+ 'xhhrsaJnDuybcpVhcr7UNKjSZ0S59tU3hpRiEz6hO+Nc/OSSLkvalG0VKrxOln7J\n' +
57
+ 'LK/h3rNS/l6wDZ5S/KqsI6CYtV2ZLpn3ahLrizvEYNY038Qcm38qMWx+VJAvZ4di\n' +
58
+ 'qqmW7RLIsLT59SWmpXdhFKnkYYGhxrk1Mwl22dBTJNY5SbriU5G3gWgzYkm8pgHr\n' +
59
+ '6CtrXch9ciJAcDJehPrKXNvNDOdUh8EW3fekNJerF1lWcwQg44/12v8sDPyfbaKB\n' +
60
+ 'dQIDAQAB\n' +
61
+ '-----END PUBLIC KEY-----'
62
+
63
+ var server = http.createServer(function (req, res) {
64
+ var parsed = httpSignature.parseRequest(req)
65
+ var publicKeyPEM = publicKeyPEMs[parsed.keyId]
66
+ var verified = httpSignature.verifySignature(parsed, publicKeyPEM)
67
+ res.writeHead(verified ? 200 : 400)
68
+ res.end()
69
+ })
70
+
71
+ tape('setup', function (t) {
72
+ server.listen(0, function () {
73
+ server.url = 'http://localhost:' + this.address().port
74
+ t.end()
75
+ })
76
+ })
77
+
78
+ tape('correct key', function (t) {
79
+ var options = {
80
+ httpSignature: {
81
+ keyId: 'key-1',
82
+ key: privateKeyPEMs['key-1']
83
+ }
84
+ }
85
+ request(server.url, options, function (err, res, body) {
86
+ t.equal(err, null)
87
+ t.equal(200, res.statusCode)
88
+ t.end()
89
+ })
90
+ })
91
+
92
+ tape('incorrect key', function (t) {
93
+ var options = {
94
+ httpSignature: {
95
+ keyId: 'key-2',
96
+ key: privateKeyPEMs['key-1']
97
+ }
98
+ }
99
+ request(server.url, options, function (err, res, body) {
100
+ t.equal(err, null)
101
+ t.equal(400, res.statusCode)
102
+ t.end()
103
+ })
104
+ })
105
+
106
+ tape('cleanup', function (t) {
107
+ server.close(function () {
108
+ t.end()
109
+ })
110
+ })
@@ -0,0 +1,112 @@
1
+ 'use strict'
2
+
3
+ var http = require('http')
4
+ var https = require('https')
5
+ var destroyable = require('server-destroy')
6
+ var server = require('./server')
7
+ var request = require('../index')
8
+ var tape = require('tape')
9
+
10
+ var fauxRequestsMade
11
+
12
+ function clearFauxRequests () {
13
+ fauxRequestsMade = { http: 0, https: 0 }
14
+ }
15
+
16
+ function wrapRequest (name, module) {
17
+ // Just like the http or https module, but note when a request is made.
18
+ var wrapped = {}
19
+ Object.keys(module).forEach(function (key) {
20
+ var value = module[key]
21
+
22
+ if (key === 'request') {
23
+ wrapped[key] = function (/* options, callback */) {
24
+ fauxRequestsMade[name] += 1
25
+ return value.apply(this, arguments)
26
+ }
27
+ } else {
28
+ wrapped[key] = value
29
+ }
30
+ })
31
+
32
+ return wrapped
33
+ }
34
+
35
+ var fauxHTTP = wrapRequest('http', http)
36
+ var fauxHTTPS = wrapRequest('https', https)
37
+ var plainServer = server.createServer()
38
+ var httpsServer = server.createSSLServer()
39
+
40
+ destroyable(plainServer)
41
+ destroyable(httpsServer)
42
+
43
+ tape('setup', function (t) {
44
+ plainServer.listen(0, function () {
45
+ plainServer.on('/plain', function (req, res) {
46
+ res.writeHead(200)
47
+ res.end('plain')
48
+ })
49
+ plainServer.on('/to_https', function (req, res) {
50
+ res.writeHead(301, { 'location': 'https://localhost:' + httpsServer.port + '/https' })
51
+ res.end()
52
+ })
53
+
54
+ httpsServer.listen(0, function () {
55
+ httpsServer.on('/https', function (req, res) {
56
+ res.writeHead(200)
57
+ res.end('https')
58
+ })
59
+ httpsServer.on('/to_plain', function (req, res) {
60
+ res.writeHead(302, { 'location': 'http://localhost:' + plainServer.port + '/plain' })
61
+ res.end()
62
+ })
63
+
64
+ t.end()
65
+ })
66
+ })
67
+ })
68
+
69
+ function runTests (name, httpModules) {
70
+ tape(name, function (t) {
71
+ var toHttps = 'http://localhost:' + plainServer.port + '/to_https'
72
+ var toPlain = 'https://localhost:' + httpsServer.port + '/to_plain'
73
+ var options = { httpModules: httpModules, strictSSL: false }
74
+ var modulesTest = httpModules || {}
75
+
76
+ clearFauxRequests()
77
+
78
+ request(toHttps, options, function (err, res, body) {
79
+ t.equal(err, null)
80
+ t.equal(res.statusCode, 200)
81
+ t.equal(body, 'https', 'Received HTTPS server body')
82
+
83
+ t.equal(fauxRequestsMade.http, modulesTest['http:'] ? 1 : 0)
84
+ t.equal(fauxRequestsMade.https, modulesTest['https:'] ? 1 : 0)
85
+
86
+ request(toPlain, options, function (err, res, body) {
87
+ t.equal(err, null)
88
+ t.equal(res.statusCode, 200)
89
+ t.equal(body, 'plain', 'Received HTTPS server body')
90
+
91
+ t.equal(fauxRequestsMade.http, modulesTest['http:'] ? 2 : 0)
92
+ t.equal(fauxRequestsMade.https, modulesTest['https:'] ? 2 : 0)
93
+
94
+ t.end()
95
+ })
96
+ })
97
+ })
98
+ }
99
+
100
+ runTests('undefined')
101
+ runTests('empty', {})
102
+ runTests('http only', { 'http:': fauxHTTP })
103
+ runTests('https only', { 'https:': fauxHTTPS })
104
+ runTests('http and https', { 'http:': fauxHTTP, 'https:': fauxHTTPS })
105
+
106
+ tape('cleanup', function (t) {
107
+ plainServer.destroy(function () {
108
+ httpsServer.destroy(function () {
109
+ t.end()
110
+ })
111
+ })
112
+ })
@@ -0,0 +1,116 @@
1
+ 'use strict'
2
+
3
+ // a test where we validate the siguature of the keys
4
+ // otherwise exactly the same as the ssl test
5
+
6
+ var server = require('./server')
7
+ var request = require('../index')
8
+ var fs = require('fs')
9
+ var path = require('path')
10
+ var tape = require('tape')
11
+
12
+ var s = server.createSSLServer()
13
+ var caFile = path.resolve(__dirname, 'ssl/ca/ca.crt')
14
+ var ca = fs.readFileSync(caFile)
15
+ var opts = {
16
+ ciphers: 'AES256-SHA',
17
+ key: path.resolve(__dirname, 'ssl/ca/server.key'),
18
+ cert: path.resolve(__dirname, 'ssl/ca/server.crt')
19
+ }
20
+ var sStrict = server.createSSLServer(opts)
21
+
22
+ function runAllTests (strict, s) {
23
+ var strictMsg = (strict ? 'strict ' : 'relaxed ')
24
+
25
+ tape(strictMsg + 'setup', function (t) {
26
+ s.listen(0, function () {
27
+ t.end()
28
+ })
29
+ })
30
+
31
+ function runTest (name, test) {
32
+ tape(strictMsg + name, function (t) {
33
+ s.on('/' + name, test.resp)
34
+ test.uri = s.url + '/' + name
35
+ if (strict) {
36
+ test.strictSSL = true
37
+ test.ca = ca
38
+ test.headers = { host: 'testing.request.mikealrogers.com' }
39
+ } else {
40
+ test.rejectUnauthorized = false
41
+ }
42
+ request(test, function (err, resp, body) {
43
+ t.equal(err, null)
44
+ if (test.expectBody) {
45
+ t.deepEqual(test.expectBody, body)
46
+ }
47
+ t.end()
48
+ })
49
+ })
50
+ }
51
+
52
+ runTest('testGet', {
53
+ resp: server.createGetResponse('TESTING!'), expectBody: 'TESTING!'
54
+ })
55
+
56
+ runTest('testGetChunkBreak', {
57
+ resp: server.createChunkResponse(
58
+ [ Buffer.from([239]),
59
+ Buffer.from([163]),
60
+ Buffer.from([191]),
61
+ Buffer.from([206]),
62
+ Buffer.from([169]),
63
+ Buffer.from([226]),
64
+ Buffer.from([152]),
65
+ Buffer.from([131])
66
+ ]),
67
+ expectBody: '\uf8ff\u03a9\u2603'
68
+ })
69
+
70
+ runTest('testGetJSON', {
71
+ resp: server.createGetResponse('{"test":true}', 'application/json'), json: true, expectBody: {'test': true}
72
+ })
73
+
74
+ runTest('testPutString', {
75
+ resp: server.createPostValidator('PUTTINGDATA'), method: 'PUT', body: 'PUTTINGDATA'
76
+ })
77
+
78
+ runTest('testPutBuffer', {
79
+ resp: server.createPostValidator('PUTTINGDATA'), method: 'PUT', body: Buffer.from('PUTTINGDATA')
80
+ })
81
+
82
+ runTest('testPutJSON', {
83
+ resp: server.createPostValidator(JSON.stringify({foo: 'bar'})), method: 'PUT', json: {foo: 'bar'}
84
+ })
85
+
86
+ runTest('testPutMultipart', {
87
+ resp: server.createPostValidator(
88
+ '--__BOUNDARY__\r\n' +
89
+ 'content-type: text/html\r\n' +
90
+ '\r\n' +
91
+ '<html><body>Oh hi.</body></html>' +
92
+ '\r\n--__BOUNDARY__\r\n\r\n' +
93
+ 'Oh hi.' +
94
+ '\r\n--__BOUNDARY__--'
95
+ ),
96
+ method: 'PUT',
97
+ multipart: [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'},
98
+ {'body': 'Oh hi.'}
99
+ ]
100
+ })
101
+
102
+ tape(strictMsg + 'cleanup', function (t) {
103
+ s.close(function () {
104
+ t.end()
105
+ })
106
+ })
107
+ }
108
+
109
+ runAllTests(false, s)
110
+
111
+ if (!process.env.running_under_istanbul) {
112
+ // somehow this test modifies the process state
113
+ // test coverage runs all tests in a single process via tape
114
+ // executing this test causes one of the tests in test-tunnel.js to throw
115
+ runAllTests(true, sStrict)
116
+ }