@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,148 @@
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, res) {
8
+ res.statusCode = 200
9
+ res.end('asdf')
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('pool', function (t) {
20
+ request({
21
+ url: s.url,
22
+ pool: false
23
+ }, function (err, res, body) {
24
+ t.equal(err, null)
25
+ t.equal(res.statusCode, 200)
26
+ t.equal(body, 'asdf')
27
+
28
+ var agent = res.request.agent
29
+ t.equal(agent, false)
30
+ t.end()
31
+ })
32
+ })
33
+
34
+ tape('forever', function (t) {
35
+ var r = request({
36
+ url: s.url,
37
+ forever: true,
38
+ pool: {maxSockets: 1024}
39
+ }, function (err, res, body) {
40
+ // explicitly shut down the agent
41
+ if (typeof r.agent.destroy === 'function') {
42
+ r.agent.destroy()
43
+ } else {
44
+ // node < 0.12
45
+ Object.keys(r.agent.sockets).forEach(function (name) {
46
+ r.agent.sockets[name].forEach(function (socket) {
47
+ socket.end()
48
+ })
49
+ })
50
+ }
51
+
52
+ t.equal(err, null)
53
+ t.equal(res.statusCode, 200)
54
+ t.equal(body, 'asdf')
55
+
56
+ var agent = res.request.agent
57
+ t.equal(agent.maxSockets, 1024)
58
+ t.end()
59
+ })
60
+ })
61
+
62
+ tape('forever, should use same agent in sequential requests', function (t) {
63
+ var r = request.defaults({
64
+ forever: true
65
+ })
66
+ var req1 = r(s.url)
67
+ var req2 = r(s.url + '/somepath')
68
+ req1.abort()
69
+ req2.abort()
70
+ if (typeof req1.agent.destroy === 'function') {
71
+ req1.agent.destroy()
72
+ }
73
+ if (typeof req2.agent.destroy === 'function') {
74
+ req2.agent.destroy()
75
+ }
76
+ t.equal(req1.agent, req2.agent)
77
+ t.end()
78
+ })
79
+
80
+ tape('forever, should use same agent in sequential requests(with pool.maxSockets)', function (t) {
81
+ var r = request.defaults({
82
+ forever: true,
83
+ pool: {maxSockets: 1024}
84
+ })
85
+ var req1 = r(s.url)
86
+ var req2 = r(s.url + '/somepath')
87
+ req1.abort()
88
+ req2.abort()
89
+ if (typeof req1.agent.destroy === 'function') {
90
+ req1.agent.destroy()
91
+ }
92
+ if (typeof req2.agent.destroy === 'function') {
93
+ req2.agent.destroy()
94
+ }
95
+ t.equal(req1.agent.maxSockets, 1024)
96
+ t.equal(req1.agent, req2.agent)
97
+ t.end()
98
+ })
99
+
100
+ tape('forever, should use same agent in request() and request.verb', function (t) {
101
+ var r = request.defaults({
102
+ forever: true,
103
+ pool: {maxSockets: 1024}
104
+ })
105
+ var req1 = r(s.url)
106
+ var req2 = r.get(s.url)
107
+ req1.abort()
108
+ req2.abort()
109
+ if (typeof req1.agent.destroy === 'function') {
110
+ req1.agent.destroy()
111
+ }
112
+ if (typeof req2.agent.destroy === 'function') {
113
+ req2.agent.destroy()
114
+ }
115
+ t.equal(req1.agent.maxSockets, 1024)
116
+ t.equal(req1.agent, req2.agent)
117
+ t.end()
118
+ })
119
+
120
+ tape('should use different agent if pool option specified', function (t) {
121
+ var r = request.defaults({
122
+ forever: true,
123
+ pool: {maxSockets: 1024}
124
+ })
125
+ var req1 = r(s.url)
126
+ var req2 = r.get({
127
+ url: s.url,
128
+ pool: {maxSockets: 20}
129
+ })
130
+ req1.abort()
131
+ req2.abort()
132
+ if (typeof req1.agent.destroy === 'function') {
133
+ req1.agent.destroy()
134
+ }
135
+ if (typeof req2.agent.destroy === 'function') {
136
+ req2.agent.destroy()
137
+ }
138
+ t.equal(req1.agent.maxSockets, 1024)
139
+ t.equal(req2.agent.maxSockets, 20)
140
+ t.notEqual(req1.agent, req2.agent)
141
+ t.end()
142
+ })
143
+
144
+ tape('cleanup', function (t) {
145
+ s.close(function () {
146
+ t.end()
147
+ })
148
+ })
@@ -0,0 +1,53 @@
1
+ 'use strict'
2
+
3
+ var http = require('http')
4
+ var request = require('../index')
5
+ var tape = require('tape')
6
+ var Promise = require('bluebird')
7
+
8
+ var s = http.createServer(function (req, res) {
9
+ res.writeHead(200, {})
10
+ res.end('ok')
11
+ })
12
+
13
+ tape('setup', function (t) {
14
+ s.listen(0, function () {
15
+ s.url = 'http://localhost:' + this.address().port
16
+ t.end()
17
+ })
18
+ })
19
+
20
+ tape('promisify convenience method', function (t) {
21
+ var get = request.get
22
+ var p = Promise.promisify(get, {multiArgs: true})
23
+ p(s.url)
24
+ .then(function (results) {
25
+ var res = results[0]
26
+ t.equal(res.statusCode, 200)
27
+ t.end()
28
+ })
29
+ })
30
+
31
+ tape('promisify request function', function (t) {
32
+ var p = Promise.promisify(request, {multiArgs: true})
33
+ p(s.url)
34
+ .spread(function (res, body) {
35
+ t.equal(res.statusCode, 200)
36
+ t.end()
37
+ })
38
+ })
39
+
40
+ tape('promisify all methods', function (t) {
41
+ Promise.promisifyAll(request, {multiArgs: true})
42
+ request.getAsync(s.url)
43
+ .spread(function (res, body) {
44
+ t.equal(res.statusCode, 200)
45
+ t.end()
46
+ })
47
+ })
48
+
49
+ tape('cleanup', function (t) {
50
+ s.close(function () {
51
+ t.end()
52
+ })
53
+ })
@@ -0,0 +1,80 @@
1
+ 'use strict'
2
+
3
+ var request = require('../index')
4
+ var tape = require('tape')
5
+
6
+ var called = false
7
+ var proxiedHost = 'google.com'
8
+ var data = ''
9
+
10
+ var s = require('net').createServer(function (sock) {
11
+ called = true
12
+ sock.once('data', function (c) {
13
+ data += c
14
+
15
+ sock.write('HTTP/1.1 200 OK\r\n\r\n')
16
+
17
+ sock.once('data', function (c) {
18
+ data += c
19
+
20
+ sock.write('HTTP/1.1 200 OK\r\n')
21
+ sock.write('content-type: text/plain\r\n')
22
+ sock.write('content-length: 5\r\n')
23
+ sock.write('\r\n')
24
+ sock.end('derp\n')
25
+ })
26
+ })
27
+ })
28
+
29
+ tape('setup', function (t) {
30
+ s.listen(0, function () {
31
+ s.url = 'http://localhost:' + this.address().port
32
+ t.end()
33
+ })
34
+ })
35
+
36
+ tape('proxy', function (t) {
37
+ request({
38
+ tunnel: true,
39
+ url: 'http://' + proxiedHost,
40
+ proxy: s.url,
41
+ headers: {
42
+ 'Proxy-Authorization': 'Basic dXNlcjpwYXNz',
43
+ 'authorization': 'Token deadbeef',
44
+ 'dont-send-to-proxy': 'ok',
45
+ 'dont-send-to-dest': 'ok',
46
+ 'accept': 'yo',
47
+ 'user-agent': 'just another foobar'
48
+ },
49
+ proxyHeaderExclusiveList: ['Dont-send-to-dest']
50
+ }, function (err, res, body) {
51
+ t.equal(err, null)
52
+ t.equal(res.statusCode, 200)
53
+ t.equal(body, 'derp\n')
54
+ var re = new RegExp([
55
+ 'CONNECT google.com:80 HTTP/1.1',
56
+ 'Proxy-Authorization: Basic dXNlcjpwYXNz',
57
+ 'dont-send-to-dest: ok',
58
+ 'accept: yo',
59
+ 'user-agent: just another foobar',
60
+ 'host: google.com:80',
61
+ 'Connection: close',
62
+ '',
63
+ 'GET / HTTP/1.1',
64
+ 'authorization: Token deadbeef',
65
+ 'dont-send-to-proxy: ok',
66
+ 'accept: yo',
67
+ 'user-agent: just another foobar',
68
+ 'host: google.com'
69
+ ].join('\r\n'))
70
+ t.equal(true, re.test(data))
71
+ t.equal(called, true, 'the request must be made to the proxy server')
72
+ t.end()
73
+ })
74
+ })
75
+
76
+ tape('cleanup', function (t) {
77
+ s.close(function () {
78
+ t.end()
79
+ })
80
+ })
@@ -0,0 +1,304 @@
1
+ 'use strict'
2
+
3
+ var server = require('./server')
4
+ var request = require('../index')
5
+ var tape = require('tape')
6
+
7
+ var s = server.createServer()
8
+ var currResponseHandler
9
+
10
+ ['http://google.com/', 'https://google.com/'].forEach(function (url) {
11
+ s.on(url, function (req, res) {
12
+ currResponseHandler(req, res)
13
+ res.writeHeader(200)
14
+ res.end('ok')
15
+ })
16
+ })
17
+
18
+ var proxyEnvVars = [
19
+ 'http_proxy',
20
+ 'HTTP_PROXY',
21
+ 'https_proxy',
22
+ 'HTTPS_PROXY',
23
+ 'no_proxy',
24
+ 'NO_PROXY'
25
+ ]
26
+
27
+ // Set up and run a proxy test. All environment variables pertaining to
28
+ // proxies will be deleted before each test. Specify environment variables as
29
+ // `options.env`; all other keys on `options` will be passed as additional
30
+ // options to `request`.
31
+ //
32
+ // If `responseHandler` is a function, it should perform asserts on the server
33
+ // response. It will be called with parameters (t, req, res). Otherwise,
34
+ // `responseHandler` should be truthy to indicate that the proxy should be used
35
+ // for this request, or falsy to indicate that the proxy should not be used for
36
+ // this request.
37
+ function runTest (name, options, responseHandler) {
38
+ tape(name, function (t) {
39
+ proxyEnvVars.forEach(function (v) {
40
+ delete process.env[v]
41
+ })
42
+ if (options.env) {
43
+ for (var v in options.env) {
44
+ process.env[v] = options.env[v]
45
+ }
46
+ delete options.env
47
+ }
48
+
49
+ var called = false
50
+ currResponseHandler = function (req, res) {
51
+ if (responseHandler) {
52
+ called = true
53
+ t.equal(req.headers.host, 'google.com')
54
+ if (typeof responseHandler === 'function') {
55
+ responseHandler(t, req, res)
56
+ }
57
+ } else {
58
+ t.fail('proxy response should not be called')
59
+ }
60
+ }
61
+
62
+ options.url = options.url || 'http://google.com'
63
+ request(options, function (err, res, body) {
64
+ if (responseHandler && !called) {
65
+ t.fail('proxy response should be called')
66
+ }
67
+ t.equal(err, null)
68
+ t.equal(res.statusCode, 200)
69
+ if (responseHandler) {
70
+ if (body.length > 100) {
71
+ body = body.substring(0, 100)
72
+ }
73
+ t.equal(body, 'ok')
74
+ } else {
75
+ t.equal(/^<!doctype html>/i.test(body), true)
76
+ }
77
+ t.end()
78
+ })
79
+ })
80
+ }
81
+
82
+ function addTests () {
83
+ // If the `runTest` function is changed, run the following command and make
84
+ // sure both of these tests fail:
85
+ //
86
+ // TEST_PROXY_HARNESS=y node tests/test-proxy.js
87
+
88
+ if (process.env.TEST_PROXY_HARNESS) {
89
+ runTest('should fail with "proxy response should not be called"', {
90
+ proxy: s.url
91
+ }, false)
92
+
93
+ runTest('should fail with "proxy response should be called"', {
94
+ proxy: null
95
+ }, true)
96
+ } else {
97
+ // Run the real tests
98
+
99
+ runTest('basic proxy', {
100
+ proxy: s.url,
101
+ headers: {
102
+ 'proxy-authorization': 'Token Fooblez'
103
+ }
104
+ }, function (t, req, res) {
105
+ t.equal(req.headers['proxy-authorization'], 'Token Fooblez')
106
+ })
107
+
108
+ runTest('proxy auth without uri auth', {
109
+ proxy: 'http://user:pass@localhost:' + s.port
110
+ }, function (t, req, res) {
111
+ t.equal(req.headers['proxy-authorization'], 'Basic dXNlcjpwYXNz')
112
+ })
113
+
114
+ // http: urls and basic proxy settings
115
+
116
+ runTest('HTTP_PROXY environment variable and http: url', {
117
+ env: { HTTP_PROXY: s.url }
118
+ }, true)
119
+
120
+ runTest('http_proxy environment variable and http: url', {
121
+ env: { http_proxy: s.url }
122
+ }, true)
123
+
124
+ runTest('HTTPS_PROXY environment variable and http: url', {
125
+ env: { HTTPS_PROXY: s.url }
126
+ }, false)
127
+
128
+ runTest('https_proxy environment variable and http: url', {
129
+ env: { https_proxy: s.url }
130
+ }, false)
131
+
132
+ // https: urls and basic proxy settings
133
+
134
+ runTest('HTTP_PROXY environment variable and https: url', {
135
+ env: { HTTP_PROXY: s.url },
136
+ url: 'https://google.com',
137
+ tunnel: false,
138
+ pool: false
139
+ }, true)
140
+
141
+ runTest('http_proxy environment variable and https: url', {
142
+ env: { http_proxy: s.url },
143
+ url: 'https://google.com',
144
+ tunnel: false
145
+ }, true)
146
+
147
+ runTest('HTTPS_PROXY environment variable and https: url', {
148
+ env: { HTTPS_PROXY: s.url },
149
+ url: 'https://google.com',
150
+ tunnel: false
151
+ }, true)
152
+
153
+ runTest('https_proxy environment variable and https: url', {
154
+ env: { https_proxy: s.url },
155
+ url: 'https://google.com',
156
+ tunnel: false
157
+ }, true)
158
+
159
+ runTest('multiple environment variables and https: url', {
160
+ env: {
161
+ HTTPS_PROXY: s.url,
162
+ HTTP_PROXY: 'http://localhost:0/'
163
+ },
164
+ url: 'https://google.com',
165
+ tunnel: false
166
+ }, true)
167
+
168
+ // no_proxy logic
169
+
170
+ runTest('NO_PROXY hostnames are case insensitive', {
171
+ env: {
172
+ HTTP_PROXY: s.url,
173
+ NO_PROXY: 'GOOGLE.COM'
174
+ }
175
+ }, false)
176
+
177
+ runTest('NO_PROXY hostnames are case insensitive 2', {
178
+ env: {
179
+ http_proxy: s.url,
180
+ NO_PROXY: 'GOOGLE.COM'
181
+ }
182
+ }, false)
183
+
184
+ runTest('NO_PROXY hostnames are case insensitive 3', {
185
+ env: {
186
+ HTTP_PROXY: s.url,
187
+ no_proxy: 'GOOGLE.COM'
188
+ }
189
+ }, false)
190
+
191
+ runTest('NO_PROXY ignored with explicit proxy passed', {
192
+ env: { NO_PROXY: '*' },
193
+ proxy: s.url
194
+ }, true)
195
+
196
+ runTest('NO_PROXY overrides HTTP_PROXY for specific hostname', {
197
+ env: {
198
+ HTTP_PROXY: s.url,
199
+ NO_PROXY: 'google.com'
200
+ }
201
+ }, false)
202
+
203
+ runTest('no_proxy overrides HTTP_PROXY for specific hostname', {
204
+ env: {
205
+ HTTP_PROXY: s.url,
206
+ no_proxy: 'google.com'
207
+ }
208
+ }, false)
209
+
210
+ runTest('NO_PROXY does not override HTTP_PROXY if no hostnames match', {
211
+ env: {
212
+ HTTP_PROXY: s.url,
213
+ NO_PROXY: 'foo.bar,bar.foo'
214
+ }
215
+ }, true)
216
+
217
+ runTest('NO_PROXY overrides HTTP_PROXY if a hostname matches', {
218
+ env: {
219
+ HTTP_PROXY: s.url,
220
+ NO_PROXY: 'foo.bar,google.com'
221
+ }
222
+ }, false)
223
+
224
+ runTest('NO_PROXY allows an explicit port', {
225
+ env: {
226
+ HTTP_PROXY: s.url,
227
+ NO_PROXY: 'google.com:80'
228
+ }
229
+ }, false)
230
+
231
+ runTest('NO_PROXY only overrides HTTP_PROXY if the port matches', {
232
+ env: {
233
+ HTTP_PROXY: s.url,
234
+ NO_PROXY: 'google.com:1234'
235
+ }
236
+ }, true)
237
+
238
+ runTest('NO_PROXY=* should override HTTP_PROXY for all hosts', {
239
+ env: {
240
+ HTTP_PROXY: s.url,
241
+ NO_PROXY: '*'
242
+ }
243
+ }, false)
244
+
245
+ runTest('NO_PROXY should override HTTP_PROXY for all subdomains', {
246
+ env: {
247
+ HTTP_PROXY: s.url,
248
+ NO_PROXY: 'google.com'
249
+ },
250
+ headers: { host: 'www.google.com' }
251
+ }, false)
252
+
253
+ runTest('NO_PROXY should not override HTTP_PROXY for partial domain matches', {
254
+ env: {
255
+ HTTP_PROXY: s.url,
256
+ NO_PROXY: 'oogle.com'
257
+ }
258
+ }, true)
259
+
260
+ runTest('NO_PROXY with port should not override HTTP_PROXY for partial domain matches', {
261
+ env: {
262
+ HTTP_PROXY: s.url,
263
+ NO_PROXY: 'oogle.com:80'
264
+ }
265
+ }, true)
266
+
267
+ // misc
268
+
269
+ // this fails if the check 'isMatchedAt > -1' in lib/getProxyFromURI.js is
270
+ // missing or broken
271
+ runTest('http_proxy with length of one more than the URL', {
272
+ env: {
273
+ HTTP_PROXY: s.url,
274
+ NO_PROXY: 'elgoog1.com' // one more char than google.com
275
+ }
276
+ }, true)
277
+
278
+ runTest('proxy: null should override HTTP_PROXY', {
279
+ env: { HTTP_PROXY: s.url },
280
+ proxy: null,
281
+ timeout: 500
282
+ }, false)
283
+
284
+ runTest('uri auth without proxy auth', {
285
+ url: 'http://user:pass@google.com',
286
+ proxy: s.url
287
+ }, function (t, req, res) {
288
+ t.equal(req.headers['proxy-authorization'], undefined)
289
+ t.equal(req.headers.authorization, 'Basic dXNlcjpwYXNz')
290
+ })
291
+ }
292
+ }
293
+
294
+ tape('setup', function (t) {
295
+ s.listen(0, function () {
296
+ addTests()
297
+ tape('cleanup', function (t) {
298
+ s.close(function () {
299
+ t.end()
300
+ })
301
+ })
302
+ t.end()
303
+ })
304
+ })
@@ -0,0 +1,135 @@
1
+ 'use strict'
2
+
3
+ var request = require('../index')
4
+ var tape = require('tape')
5
+
6
+ // Run a querystring test. `options` can have the following keys:
7
+ // - suffix : a string to be added to the URL
8
+ // - qs : an object to be passed to request's `qs` option
9
+ // - qsParseOptions : an object to be passed to request's `qsParseOptions` option
10
+ // - qsStringifyOptions : an object to be passed to request's `qsStringifyOptions` option
11
+ // - afterRequest : a function to execute after creating the request
12
+ // - expected : the expected path of the request
13
+ // - expectedQuerystring : expected path when using the querystring library
14
+ function runTest (name, options) {
15
+ var uri = 'http://www.google.com' + (options.suffix || '')
16
+ var opts = {
17
+ uri: uri,
18
+ qsParseOptions: options.qsParseOptions,
19
+ qsStringifyOptions: options.qsStringifyOptions
20
+ }
21
+
22
+ if (options.qs) {
23
+ opts.qs = options.qs
24
+ }
25
+
26
+ tape(name + ' - using qs', function (t) {
27
+ var r = request.get(opts)
28
+ if (typeof options.afterRequest === 'function') {
29
+ options.afterRequest(r)
30
+ }
31
+ process.nextTick(function () {
32
+ t.equal(r.path, options.expected)
33
+ r.abort()
34
+ t.end()
35
+ })
36
+ })
37
+
38
+ tape(name + ' - using querystring', function (t) {
39
+ opts.useQuerystring = true
40
+ var r = request.get(opts)
41
+ if (typeof options.afterRequest === 'function') {
42
+ options.afterRequest(r)
43
+ }
44
+ process.nextTick(function () {
45
+ t.equal(r.path, options.expectedQuerystring || options.expected)
46
+ r.abort()
47
+ t.end()
48
+ })
49
+ })
50
+ }
51
+
52
+ function esc (str) {
53
+ return str
54
+ .replace(/\[/g, '%5B')
55
+ .replace(/\]/g, '%5D')
56
+ }
57
+
58
+ runTest('adding a querystring', {
59
+ qs: { q: 'search' },
60
+ expected: '/?q=search'
61
+ })
62
+
63
+ runTest('replacing a querystring value', {
64
+ suffix: '?q=abc',
65
+ qs: { q: 'search' },
66
+ expected: '/?q=search'
67
+ })
68
+
69
+ runTest('appending a querystring value to the ones present in the uri', {
70
+ suffix: '?x=y',
71
+ qs: { q: 'search' },
72
+ expected: '/?x=y&q=search'
73
+ })
74
+
75
+ runTest('leaving a querystring alone', {
76
+ suffix: '?x=y',
77
+ expected: '/?x=y'
78
+ })
79
+
80
+ runTest('giving empty qs property', {
81
+ qs: {},
82
+ expected: '/'
83
+ })
84
+
85
+ runTest('modifying the qs after creating the request', {
86
+ qs: {},
87
+ afterRequest: function (r) {
88
+ r.qs({ q: 'test' })
89
+ },
90
+ expected: '/?q=test'
91
+ })
92
+
93
+ runTest('a query with an object for a value', {
94
+ qs: { where: { foo: 'bar' } },
95
+ expected: esc('/?where[foo]=bar'),
96
+ expectedQuerystring: '/?where='
97
+ })
98
+
99
+ runTest('a query with an array for a value', {
100
+ qs: { order: ['bar', 'desc'] },
101
+ expected: esc('/?order[0]=bar&order[1]=desc'),
102
+ expectedQuerystring: '/?order=bar&order=desc'
103
+ })
104
+
105
+ runTest('pass options to the qs module via the qsParseOptions key', {
106
+ suffix: '?a=1;b=2',
107
+ qs: {},
108
+ qsParseOptions: { delimiter: ';' },
109
+ qsStringifyOptions: { delimiter: ';' },
110
+ expected: esc('/?a=1;b=2'),
111
+ expectedQuerystring: '/?a=1%3Bb%3D2'
112
+ })
113
+
114
+ runTest('pass options to the qs module via the qsStringifyOptions key', {
115
+ qs: { order: ['bar', 'desc'] },
116
+ qsStringifyOptions: { arrayFormat: 'brackets' },
117
+ expected: esc('/?order[]=bar&order[]=desc'),
118
+ expectedQuerystring: '/?order=bar&order=desc'
119
+ })
120
+
121
+ runTest('pass options to the querystring module via the qsParseOptions key', {
122
+ suffix: '?a=1;b=2',
123
+ qs: {},
124
+ qsParseOptions: { sep: ';' },
125
+ qsStringifyOptions: { sep: ';' },
126
+ expected: esc('/?a=1%3Bb%3D2'),
127
+ expectedQuerystring: '/?a=1;b=2'
128
+ })
129
+
130
+ runTest('pass options to the querystring module via the qsStringifyOptions key', {
131
+ qs: { order: ['bar', 'desc'] },
132
+ qsStringifyOptions: { sep: ';' },
133
+ expected: esc('/?order[0]=bar&order[1]=desc'),
134
+ expectedQuerystring: '/?order=bar;order=desc'
135
+ })