@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,61 @@
1
+ 'use strict'
2
+
3
+ var http = require('http')
4
+ var assert = require('assert')
5
+ var request = require('../index')
6
+ var tape = require('tape')
7
+
8
+ var server = http.createServer(function (req, resp) {
9
+ resp.statusCode = 200
10
+ if (req.url === '/get') {
11
+ assert.equal(req.method, 'GET')
12
+ resp.write('content')
13
+ resp.end()
14
+ return
15
+ }
16
+ if (req.url === '/put') {
17
+ var x = ''
18
+ assert.equal(req.method, 'PUT')
19
+ req.on('data', function (chunk) {
20
+ x += chunk
21
+ })
22
+ req.on('end', function () {
23
+ assert.equal(x, 'content')
24
+ resp.write('success')
25
+ resp.end()
26
+ })
27
+ return
28
+ }
29
+ if (req.url === '/proxy') {
30
+ assert.equal(req.method, 'PUT')
31
+ req.pipe(request(server.url + '/put')).pipe(resp)
32
+ return
33
+ }
34
+ if (req.url === '/test') {
35
+ request(server.url + '/get').pipe(request.put(server.url + '/proxy')).pipe(resp)
36
+ return
37
+ }
38
+ throw new Error('Unknown url', req.url)
39
+ })
40
+
41
+ tape('setup', function (t) {
42
+ server.listen(0, function () {
43
+ server.url = 'http://localhost:' + this.address().port
44
+ t.end()
45
+ })
46
+ })
47
+
48
+ tape('chained one-line proxying', function (t) {
49
+ request(server.url + '/test', function (err, res, body) {
50
+ t.equal(err, null)
51
+ t.equal(res.statusCode, 200)
52
+ t.equal(body, 'success')
53
+ t.end()
54
+ })
55
+ })
56
+
57
+ tape('cleanup', function (t) {
58
+ server.close(function () {
59
+ t.end()
60
+ })
61
+ })
@@ -0,0 +1,54 @@
1
+ 'use strict'
2
+
3
+ var request = require('../index')
4
+ var http = require('http')
5
+ var tape = require('tape')
6
+
7
+ var methodsSeen = {
8
+ head: 0,
9
+ get: 0
10
+ }
11
+
12
+ var s = http.createServer(function (req, res) {
13
+ res.statusCode = 200
14
+ res.end('ok')
15
+
16
+ methodsSeen[req.method.toLowerCase()]++
17
+ })
18
+
19
+ tape('setup', function (t) {
20
+ s.listen(0, function () {
21
+ s.url = 'http://localhost:' + this.address().port
22
+ t.end()
23
+ })
24
+ })
25
+
26
+ tape('options object is not mutated', function (t) {
27
+ var url = s.url
28
+ var options = { url: url }
29
+
30
+ request.head(options, function (err, resp, body) {
31
+ t.equal(err, null)
32
+ t.equal(body, '')
33
+ t.equal(Object.keys(options).length, 1)
34
+ t.equal(options.url, url)
35
+
36
+ request.get(options, function (err, resp, body) {
37
+ t.equal(err, null)
38
+ t.equal(body, 'ok')
39
+ t.equal(Object.keys(options).length, 1)
40
+ t.equal(options.url, url)
41
+
42
+ t.equal(methodsSeen.head, 1)
43
+ t.equal(methodsSeen.get, 1)
44
+
45
+ t.end()
46
+ })
47
+ })
48
+ })
49
+
50
+ tape('cleanup', function (t) {
51
+ s.close(function () {
52
+ t.end()
53
+ })
54
+ })
@@ -0,0 +1,52 @@
1
+ 'use strict'
2
+
3
+ var server = require('./server')
4
+ var request = require('../index')
5
+ var tape = require('tape')
6
+ var destroyable = require('server-destroy')
7
+
8
+ var s = server.createServer()
9
+
10
+ destroyable(s)
11
+
12
+ tape('setup', function (t) {
13
+ s.listen(0, function () {
14
+ s.on('/options', function (req, res) {
15
+ res.writeHead(200, {
16
+ 'x-original-method': req.method,
17
+ 'allow': 'OPTIONS, GET, HEAD'
18
+ })
19
+
20
+ res.end()
21
+ })
22
+
23
+ t.end()
24
+ })
25
+ })
26
+
27
+ tape('options(string, function)', function (t) {
28
+ request.options(s.url + '/options', function (err, res) {
29
+ t.equal(err, null)
30
+ t.equal(res.statusCode, 200)
31
+ t.equal(res.headers['x-original-method'], 'OPTIONS')
32
+ t.end()
33
+ })
34
+ })
35
+
36
+ tape('options(object, function)', function (t) {
37
+ request.options({
38
+ url: s.url + '/options',
39
+ headers: { foo: 'bar' }
40
+ }, function (err, res) {
41
+ t.equal(err, null)
42
+ t.equal(res.statusCode, 200)
43
+ t.equal(res.headers['x-original-method'], 'OPTIONS')
44
+ t.end()
45
+ })
46
+ })
47
+
48
+ tape('cleanup', function (t) {
49
+ s.destroy(function () {
50
+ t.end()
51
+ })
52
+ })
@@ -0,0 +1,101 @@
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
+
9
+ function runTest (name, test) {
10
+ tape(name, function (t) {
11
+ s.on('/' + name, test.resp)
12
+ request(s.url + '/' + name, test, function (err, resp, body) {
13
+ t.equal(err, null)
14
+ if (test.expectBody) {
15
+ if (Buffer.isBuffer(test.expectBody)) {
16
+ t.equal(test.expectBody.toString(), body.toString())
17
+ } else {
18
+ t.deepEqual(test.expectBody, body)
19
+ }
20
+ }
21
+ t.end()
22
+ })
23
+ })
24
+ }
25
+
26
+ tape('setup', function (t) {
27
+ s.listen(0, function () {
28
+ t.end()
29
+ })
30
+ })
31
+
32
+ runTest('testGet', {
33
+ resp: server.createGetResponse('TESTING!'),
34
+ expectBody: 'TESTING!'
35
+ })
36
+
37
+ runTest('testGetChunkBreak', {
38
+ resp: server.createChunkResponse(
39
+ [ Buffer.from([239]),
40
+ Buffer.from([163]),
41
+ Buffer.from([191]),
42
+ Buffer.from([206]),
43
+ Buffer.from([169]),
44
+ Buffer.from([226]),
45
+ Buffer.from([152]),
46
+ Buffer.from([131])
47
+ ]),
48
+ expectBody: '\uf8ff\u03a9\u2603'
49
+ })
50
+
51
+ runTest('testGetBuffer', {
52
+ resp: server.createGetResponse(Buffer.from('TESTING!')),
53
+ encoding: null,
54
+ expectBody: Buffer.from('TESTING!')
55
+ })
56
+
57
+ runTest('testGetJSON', {
58
+ resp: server.createGetResponse('{"test":true}', 'application/json'),
59
+ json: true,
60
+ expectBody: {'test': true}
61
+ })
62
+
63
+ runTest('testPutString', {
64
+ resp: server.createPostValidator('PUTTINGDATA'),
65
+ method: 'PUT',
66
+ body: 'PUTTINGDATA'
67
+ })
68
+
69
+ runTest('testPutBuffer', {
70
+ resp: server.createPostValidator('PUTTINGDATA'),
71
+ method: 'PUT',
72
+ body: Buffer.from('PUTTINGDATA')
73
+ })
74
+
75
+ runTest('testPutJSON', {
76
+ resp: server.createPostValidator(JSON.stringify({foo: 'bar'})),
77
+ method: 'PUT',
78
+ json: {foo: 'bar'}
79
+ })
80
+
81
+ runTest('testPutMultipart', {
82
+ resp: server.createPostValidator(
83
+ '--__BOUNDARY__\r\n' +
84
+ 'content-type: text/html\r\n' +
85
+ '\r\n' +
86
+ '<html><body>Oh hi.</body></html>' +
87
+ '\r\n--__BOUNDARY__\r\n\r\n' +
88
+ 'Oh hi.' +
89
+ '\r\n--__BOUNDARY__--'
90
+ ),
91
+ method: 'PUT',
92
+ multipart: [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'},
93
+ {'body': 'Oh hi.'}
94
+ ]
95
+ })
96
+
97
+ tape('cleanup', function (t) {
98
+ s.close(function () {
99
+ t.end()
100
+ })
101
+ })
@@ -0,0 +1,55 @@
1
+ 'use strict'
2
+
3
+ var http = require('http')
4
+ var request = require('../index')
5
+ var tape = require('tape')
6
+
7
+ var port1
8
+ var port2
9
+
10
+ var s1 = http.createServer(function (req, resp) {
11
+ if (req.url === '/original') {
12
+ resp.writeHeader(302, {
13
+ 'location': '/redirected'
14
+ })
15
+ resp.end()
16
+ } else if (req.url === '/redirected') {
17
+ resp.writeHeader(200, {
18
+ 'content-type': 'text/plain'
19
+ })
20
+ resp.write('OK')
21
+ resp.end()
22
+ }
23
+ })
24
+
25
+ var s2 = http.createServer(function (req, resp) {
26
+ var x = request('http://localhost:' + port1 + '/original')
27
+ req.pipe(x)
28
+ x.pipe(resp)
29
+ })
30
+
31
+ tape('setup', function (t) {
32
+ s1.listen(0, function () {
33
+ port1 = this.address().port
34
+ s2.listen(0, function () {
35
+ port2 = this.address().port
36
+ t.end()
37
+ })
38
+ })
39
+ })
40
+
41
+ tape('piped redirect', function (t) {
42
+ request('http://localhost:' + port2 + '/original', function (err, res, body) {
43
+ t.equal(err, null)
44
+ t.equal(body, 'OK')
45
+ t.end()
46
+ })
47
+ })
48
+
49
+ tape('cleanup', function (t) {
50
+ s1.close(function () {
51
+ s2.close(function () {
52
+ t.end()
53
+ })
54
+ })
55
+ })
@@ -0,0 +1,383 @@
1
+ 'use strict'
2
+
3
+ var server = require('./server')
4
+ var stream = require('stream')
5
+ var fs = require('fs')
6
+ var request = require('../index')
7
+ var path = require('path')
8
+ var util = require('util')
9
+ var tape = require('tape')
10
+
11
+ var s = server.createServer()
12
+
13
+ s.on('/cat', function (req, res) {
14
+ if (req.method === 'GET') {
15
+ res.writeHead(200, {
16
+ 'content-type': 'text/plain-test',
17
+ 'content-length': 4
18
+ })
19
+ res.end('asdf')
20
+ } else if (req.method === 'PUT') {
21
+ var body = ''
22
+ req.on('data', function (chunk) {
23
+ body += chunk
24
+ }).on('end', function () {
25
+ res.writeHead(201)
26
+ res.end()
27
+ s.emit('catDone', req, res, body)
28
+ })
29
+ }
30
+ })
31
+
32
+ s.on('/doodle', function (req, res) {
33
+ if (req.headers['x-oneline-proxy']) {
34
+ res.setHeader('x-oneline-proxy', 'yup')
35
+ }
36
+ res.writeHead('200', { 'content-type': 'image/jpeg' })
37
+ fs.createReadStream(path.join(__dirname, 'googledoodle.jpg')).pipe(res)
38
+ })
39
+
40
+ function ValidationStream (t, str) {
41
+ this.str = str
42
+ this.buf = ''
43
+ this.on('data', function (data) {
44
+ this.buf += data
45
+ })
46
+ this.on('end', function () {
47
+ t.equal(this.str, this.buf)
48
+ })
49
+ this.writable = true
50
+ }
51
+
52
+ util.inherits(ValidationStream, stream.Stream)
53
+
54
+ ValidationStream.prototype.write = function (chunk) {
55
+ this.emit('data', chunk)
56
+ }
57
+
58
+ ValidationStream.prototype.end = function (chunk) {
59
+ if (chunk) {
60
+ this.emit('data', chunk)
61
+ }
62
+ this.emit('end')
63
+ }
64
+
65
+ tape('setup', function (t) {
66
+ s.listen(0, function () {
67
+ t.end()
68
+ })
69
+ })
70
+
71
+ tape('piping to a request object', function (t) {
72
+ s.once('/push', server.createPostValidator('mydata'))
73
+
74
+ var mydata = new stream.Stream()
75
+ mydata.readable = true
76
+
77
+ var r1 = request.put({
78
+ url: s.url + '/push'
79
+ }, function (err, res, body) {
80
+ t.equal(err, null)
81
+ t.equal(res.statusCode, 200)
82
+ t.equal(body, 'mydata')
83
+ t.end()
84
+ })
85
+ mydata.pipe(r1)
86
+
87
+ mydata.emit('data', 'mydata')
88
+ mydata.emit('end')
89
+ })
90
+
91
+ tape('piping to a request object with invalid uri', function (t) {
92
+ var mybodydata = new stream.Stream()
93
+ mybodydata.readable = true
94
+
95
+ var r2 = request.put({
96
+ url: '/bad-uri',
97
+ json: true
98
+ }, function (err, res, body) {
99
+ t.ok(err instanceof Error)
100
+ t.equal(err.message, 'Invalid URI "/bad-uri"')
101
+ t.end()
102
+ })
103
+ mybodydata.pipe(r2)
104
+
105
+ mybodydata.emit('data', JSON.stringify({ foo: 'bar' }))
106
+ mybodydata.emit('end')
107
+ })
108
+
109
+ tape('piping to a request object with a json body', function (t) {
110
+ var obj = {foo: 'bar'}
111
+ var json = JSON.stringify(obj)
112
+ s.once('/push-json', server.createPostValidator(json, 'application/json'))
113
+ var mybodydata = new stream.Stream()
114
+ mybodydata.readable = true
115
+
116
+ var r2 = request.put({
117
+ url: s.url + '/push-json',
118
+ json: true
119
+ }, function (err, res, body) {
120
+ t.equal(err, null)
121
+ t.equal(res.statusCode, 200)
122
+ t.deepEqual(body, obj)
123
+ t.end()
124
+ })
125
+ mybodydata.pipe(r2)
126
+
127
+ mybodydata.emit('data', JSON.stringify({ foo: 'bar' }))
128
+ mybodydata.emit('end')
129
+ })
130
+
131
+ tape('piping from a request object', function (t) {
132
+ s.once('/pull', server.createGetResponse('mypulldata'))
133
+
134
+ var mypulldata = new stream.Stream()
135
+ mypulldata.writable = true
136
+
137
+ request({
138
+ url: s.url + '/pull'
139
+ }).pipe(mypulldata)
140
+
141
+ var d = ''
142
+
143
+ mypulldata.write = function (chunk) {
144
+ d += chunk
145
+ }
146
+ mypulldata.end = function () {
147
+ t.equal(d, 'mypulldata')
148
+ t.end()
149
+ }
150
+ })
151
+
152
+ tape('pause when piping from a request object', function (t) {
153
+ s.once('/chunks', function (req, res) {
154
+ res.writeHead(200, {
155
+ 'content-type': 'text/plain'
156
+ })
157
+ res.write('Chunk 1')
158
+ setTimeout(function () { res.end('Chunk 2') }, 10)
159
+ })
160
+
161
+ var chunkNum = 0
162
+ var paused = false
163
+ request({
164
+ url: s.url + '/chunks'
165
+ })
166
+ .on('data', function (chunk) {
167
+ var self = this
168
+
169
+ t.notOk(paused, 'Only receive data when not paused')
170
+
171
+ ++chunkNum
172
+ if (chunkNum === 1) {
173
+ t.equal(chunk.toString(), 'Chunk 1')
174
+ self.pause()
175
+ paused = true
176
+ setTimeout(function () {
177
+ paused = false
178
+ self.resume()
179
+ }, 100)
180
+ } else {
181
+ t.equal(chunk.toString(), 'Chunk 2')
182
+ }
183
+ })
184
+ .on('end', t.end.bind(t))
185
+ })
186
+
187
+ tape('pause before piping from a request object', function (t) {
188
+ s.once('/pause-before', function (req, res) {
189
+ res.writeHead(200, {
190
+ 'content-type': 'text/plain'
191
+ })
192
+ res.end('Data')
193
+ })
194
+
195
+ var paused = true
196
+ var r = request({
197
+ url: s.url + '/pause-before'
198
+ })
199
+ r.pause()
200
+ r.on('data', function (data) {
201
+ t.notOk(paused, 'Only receive data when not paused')
202
+ t.equal(data.toString(), 'Data')
203
+ })
204
+ r.on('end', t.end.bind(t))
205
+
206
+ setTimeout(function () {
207
+ paused = false
208
+ r.resume()
209
+ }, 100)
210
+ })
211
+
212
+ var fileContents = fs.readFileSync(__filename)
213
+ function testPipeFromFile (testName, hasContentLength) {
214
+ tape(testName, function (t) {
215
+ s.once('/pushjs', function (req, res) {
216
+ if (req.method === 'PUT') {
217
+ t.equal(req.headers['content-type'], 'application/javascript')
218
+ t.equal(
219
+ req.headers['content-length'],
220
+ (hasContentLength ? '' + fileContents.length : undefined))
221
+ var body = ''
222
+ req.setEncoding('utf8')
223
+ req.on('data', function (data) {
224
+ body += data
225
+ })
226
+ req.on('end', function () {
227
+ res.end()
228
+ t.equal(body, fileContents.toString())
229
+ t.end()
230
+ })
231
+ } else {
232
+ res.end()
233
+ }
234
+ })
235
+ var r = request.put(s.url + '/pushjs')
236
+ fs.createReadStream(__filename).pipe(r)
237
+ if (hasContentLength) {
238
+ r.setHeader('content-length', fileContents.length)
239
+ }
240
+ })
241
+ }
242
+
243
+ // TODO Piping from a file does not send content-length header
244
+ testPipeFromFile('piping from a file', false)
245
+ testPipeFromFile('piping from a file with content-length', true)
246
+
247
+ tape('piping to and from same URL', function (t) {
248
+ s.once('catDone', function (req, res, body) {
249
+ t.equal(req.headers['content-type'], 'text/plain-test')
250
+ t.equal(req.headers['content-length'], '4')
251
+ t.equal(body, 'asdf')
252
+ t.end()
253
+ })
254
+ request.get(s.url + '/cat')
255
+ .pipe(request.put(s.url + '/cat'))
256
+ })
257
+
258
+ tape('piping between urls', function (t) {
259
+ s.once('/catresp', function (req, res) {
260
+ request.get(s.url + '/cat').pipe(res)
261
+ })
262
+
263
+ request.get(s.url + '/catresp', function (err, res, body) {
264
+ t.equal(err, null)
265
+ t.equal(res.headers['content-type'], 'text/plain-test')
266
+ t.equal(res.headers['content-length'], '4')
267
+ t.end()
268
+ })
269
+ })
270
+
271
+ tape('writing to file', function (t) {
272
+ var doodleWrite = fs.createWriteStream(path.join(__dirname, 'test.jpg'))
273
+
274
+ request.get(s.url + '/doodle').pipe(doodleWrite)
275
+
276
+ doodleWrite.on('close', function () {
277
+ t.deepEqual(
278
+ fs.readFileSync(path.join(__dirname, 'googledoodle.jpg')),
279
+ fs.readFileSync(path.join(__dirname, 'test.jpg')))
280
+ fs.unlinkSync(path.join(__dirname, 'test.jpg'))
281
+ t.end()
282
+ })
283
+ })
284
+
285
+ tape('one-line proxy', function (t) {
286
+ s.once('/onelineproxy', function (req, res) {
287
+ var x = request(s.url + '/doodle')
288
+ req.pipe(x)
289
+ x.pipe(res)
290
+ })
291
+
292
+ request.get({
293
+ uri: s.url + '/onelineproxy',
294
+ headers: { 'x-oneline-proxy': 'nope' }
295
+ }, function (err, res, body) {
296
+ t.equal(err, null)
297
+ t.equal(res.headers['x-oneline-proxy'], 'yup')
298
+ t.equal(body, fs.readFileSync(path.join(__dirname, 'googledoodle.jpg')).toString())
299
+ t.end()
300
+ })
301
+ })
302
+
303
+ tape('piping after response', function (t) {
304
+ s.once('/afterresponse', function (req, res) {
305
+ res.write('d')
306
+ res.end()
307
+ })
308
+
309
+ var rAfterRes = request.post(s.url + '/afterresponse')
310
+
311
+ rAfterRes.on('response', function () {
312
+ var v = new ValidationStream(t, 'd')
313
+ rAfterRes.pipe(v)
314
+ v.on('end', function () {
315
+ t.end()
316
+ })
317
+ })
318
+ })
319
+
320
+ tape('piping through a redirect', function (t) {
321
+ s.once('/forward1', function (req, res) {
322
+ res.writeHead(302, { location: '/forward2' })
323
+ res.end()
324
+ })
325
+ s.once('/forward2', function (req, res) {
326
+ res.writeHead('200', { 'content-type': 'image/png' })
327
+ res.write('d')
328
+ res.end()
329
+ })
330
+
331
+ var validateForward = new ValidationStream(t, 'd')
332
+
333
+ request.get(s.url + '/forward1').pipe(validateForward)
334
+
335
+ validateForward.on('end', function () {
336
+ t.end()
337
+ })
338
+ })
339
+
340
+ tape('pipe options', function (t) {
341
+ s.once('/opts', server.createGetResponse('opts response'))
342
+
343
+ var optsStream = new stream.Stream()
344
+ var optsData = ''
345
+
346
+ optsStream.writable = true
347
+ optsStream.write = function (buf) {
348
+ optsData += buf
349
+ if (optsData === 'opts response') {
350
+ setTimeout(function () {
351
+ t.end()
352
+ }, 10)
353
+ }
354
+ }
355
+ optsStream.end = function () {
356
+ t.fail('end called')
357
+ }
358
+
359
+ request({
360
+ url: s.url + '/opts'
361
+ }).pipe(optsStream, { end: false })
362
+ })
363
+
364
+ tape('request.pipefilter is called correctly', function (t) {
365
+ s.once('/pipefilter', function (req, res) {
366
+ res.end('d')
367
+ })
368
+ var validatePipeFilter = new ValidationStream(t, 'd')
369
+
370
+ var r3 = request.get(s.url + '/pipefilter')
371
+ r3.pipe(validatePipeFilter)
372
+ r3.pipefilter = function (res, dest) {
373
+ t.equal(res, r3.response)
374
+ t.equal(dest, validatePipeFilter)
375
+ t.end()
376
+ }
377
+ })
378
+
379
+ tape('cleanup', function (t) {
380
+ s.close(function () {
381
+ t.end()
382
+ })
383
+ })