@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.
- package/.github/ISSUE_TEMPLATE.md +56 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +13 -0
- package/.github/stale.yml +19 -0
- package/.swcrc +57 -0
- package/.travis.yml +21 -0
- package/CHANGELOG.md +717 -0
- package/CONTRIBUTING.md +81 -0
- package/biome.json +44 -0
- package/codecov.yml +2 -0
- package/disabled.appveyor.yml +36 -0
- package/dist/request.cjs +1476 -0
- package/dist/request.mjs +1474 -0
- package/examples/README.md +135 -0
- package/gulpfile.js +71 -0
- package/package.json +1 -2
- package/release.sh +45 -0
- package/tests/browser/karma.conf.js +57 -0
- package/tests/browser/ssl/ca.crt +14 -0
- package/tests/browser/ssl/server.crt +14 -0
- package/tests/browser/ssl/server.key +15 -0
- package/tests/browser/start.js +37 -0
- package/tests/browser/test.js +34 -0
- package/tests/fixtures/har.json +158 -0
- package/tests/googledoodle.jpg +0 -0
- package/tests/server.js +142 -0
- package/tests/squid.conf +76 -0
- package/tests/ssl/ca/README.md +8 -0
- package/tests/ssl/ca/ca.cnf +20 -0
- package/tests/ssl/ca/ca.crl +0 -0
- package/tests/ssl/ca/ca.crt +17 -0
- package/tests/ssl/ca/ca.csr +13 -0
- package/tests/ssl/ca/ca.key +18 -0
- package/tests/ssl/ca/ca.srl +1 -0
- package/tests/ssl/ca/client-enc.key +30 -0
- package/tests/ssl/ca/client.cnf +20 -0
- package/tests/ssl/ca/client.crt +20 -0
- package/tests/ssl/ca/client.csr +18 -0
- package/tests/ssl/ca/client.key +27 -0
- package/tests/ssl/ca/gen-all-certs.sh +6 -0
- package/tests/ssl/ca/gen-client.sh +25 -0
- package/tests/ssl/ca/gen-localhost.sh +22 -0
- package/tests/ssl/ca/gen-server.sh +18 -0
- package/tests/ssl/ca/localhost.cnf +20 -0
- package/tests/ssl/ca/localhost.crt +20 -0
- package/tests/ssl/ca/localhost.csr +18 -0
- package/tests/ssl/ca/localhost.js +33 -0
- package/tests/ssl/ca/localhost.key +27 -0
- package/tests/ssl/ca/server.cnf +19 -0
- package/tests/ssl/ca/server.crt +25 -0
- package/tests/ssl/ca/server.csr +29 -0
- package/tests/ssl/ca/server.js +34 -0
- package/tests/ssl/ca/server.key +51 -0
- package/tests/ssl/npm-ca.crt +16 -0
- package/tests/ssl/test.crt +15 -0
- package/tests/ssl/test.key +15 -0
- package/tests/test-agent.js +102 -0
- package/tests/test-agentOptions.js +51 -0
- package/tests/test-api.js +33 -0
- package/tests/test-aws.js +123 -0
- package/tests/test-baseUrl.js +133 -0
- package/tests/test-basic-auth.js +221 -0
- package/tests/test-bearer-auth.js +187 -0
- package/tests/test-body.js +154 -0
- package/tests/test-cookies.js +130 -0
- package/tests/test-defaults.js +340 -0
- package/tests/test-digest-auth.js +232 -0
- package/tests/test-emptyBody.js +56 -0
- package/tests/test-errors.js +108 -0
- package/tests/test-event-forwarding.js +39 -0
- package/tests/test-follow-all-303.js +45 -0
- package/tests/test-follow-all.js +57 -0
- package/tests/test-form-data-error.js +85 -0
- package/tests/test-form-data.js +133 -0
- package/tests/test-form-urlencoded.js +73 -0
- package/tests/test-form.js +101 -0
- package/tests/test-gzip.js +296 -0
- package/tests/test-har.js +175 -0
- package/tests/test-hawk.js +187 -0
- package/tests/test-headers.js +305 -0
- package/tests/test-http-signature.js +110 -0
- package/tests/test-httpModule.js +112 -0
- package/tests/test-https.js +116 -0
- package/tests/test-isUrl.js +120 -0
- package/tests/test-json-request.js +117 -0
- package/tests/test-localAddress.js +49 -0
- package/tests/test-multipart-encoding.js +147 -0
- package/tests/test-multipart.js +129 -0
- package/tests/test-node-debug.js +95 -0
- package/tests/test-oauth.js +721 -0
- package/tests/test-onelineproxy.js +61 -0
- package/tests/test-option-reuse.js +54 -0
- package/tests/test-options-convenience-method.js +52 -0
- package/tests/test-params.js +101 -0
- package/tests/test-piped-redirect.js +55 -0
- package/tests/test-pipes.js +383 -0
- package/tests/test-pool.js +148 -0
- package/tests/test-promise.js +53 -0
- package/tests/test-proxy-connect.js +80 -0
- package/tests/test-proxy.js +304 -0
- package/tests/test-qs.js +135 -0
- package/tests/test-redirect-auth.js +131 -0
- package/tests/test-redirect-complex.js +93 -0
- package/tests/test-redirect.js +449 -0
- package/tests/test-rfc3986.js +106 -0
- package/tests/test-stream.js +36 -0
- package/tests/test-timeout.js +260 -0
- package/tests/test-timing.js +147 -0
- package/tests/test-toJSON.js +45 -0
- package/tests/test-tunnel.js +466 -0
- package/tests/test-unix.js +74 -0
- package/tests/unicycle.jpg +0 -0
- package/request.js +0 -1553
- package/src/ZlibTransform.js +0 -27
- package/src/caseless.js +0 -118
- package/src/index.js +0 -122
- package/src/request.js +0 -967
- package/src/utils.js +0 -274
|
@@ -0,0 +1,131 @@
|
|
|
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 destroyable = require('server-destroy')
|
|
8
|
+
|
|
9
|
+
var s = server.createServer()
|
|
10
|
+
var ss = server.createSSLServer()
|
|
11
|
+
|
|
12
|
+
destroyable(s)
|
|
13
|
+
destroyable(ss)
|
|
14
|
+
|
|
15
|
+
// always send basic auth and allow non-strict SSL
|
|
16
|
+
request = request.defaults({
|
|
17
|
+
auth: {
|
|
18
|
+
user: 'test',
|
|
19
|
+
pass: 'testing'
|
|
20
|
+
},
|
|
21
|
+
rejectUnauthorized: false
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// redirect.from(proto, host).to(proto, host) returns an object with keys:
|
|
25
|
+
// src : source URL
|
|
26
|
+
// dst : destination URL
|
|
27
|
+
var redirect = {
|
|
28
|
+
from: function (fromProto, fromHost) {
|
|
29
|
+
return {
|
|
30
|
+
to: function (toProto, toHost) {
|
|
31
|
+
var fromPort = (fromProto === 'http' ? s.port : ss.port)
|
|
32
|
+
var toPort = (toProto === 'http' ? s.port : ss.port)
|
|
33
|
+
return {
|
|
34
|
+
src: util.format(
|
|
35
|
+
'%s://%s:%d/to/%s/%s',
|
|
36
|
+
fromProto, fromHost, fromPort, toProto, toHost),
|
|
37
|
+
dst: util.format(
|
|
38
|
+
'%s://%s:%d/from/%s/%s',
|
|
39
|
+
toProto, toHost, toPort, fromProto, fromHost)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function handleRequests (srv) {
|
|
47
|
+
['http', 'https'].forEach(function (proto) {
|
|
48
|
+
['localhost', '127.0.0.1'].forEach(function (host) {
|
|
49
|
+
srv.on(util.format('/to/%s/%s', proto, host), function (req, res) {
|
|
50
|
+
var r = redirect
|
|
51
|
+
.from(srv.protocol, req.headers.host.split(':')[0])
|
|
52
|
+
.to(proto, host)
|
|
53
|
+
res.writeHead(301, {
|
|
54
|
+
location: r.dst
|
|
55
|
+
})
|
|
56
|
+
res.end()
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
srv.on(util.format('/from/%s/%s', proto, host), function (req, res) {
|
|
60
|
+
res.end('auth: ' + (req.headers.authorization || '(nothing)'))
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
handleRequests(s)
|
|
67
|
+
handleRequests(ss)
|
|
68
|
+
|
|
69
|
+
function runTest (name, redir, expectAuth) {
|
|
70
|
+
tape('redirect to ' + name, function (t) {
|
|
71
|
+
request(redir.src, function (err, res, body) {
|
|
72
|
+
t.equal(err, null)
|
|
73
|
+
t.equal(res.request.uri.href, redir.dst)
|
|
74
|
+
t.equal(res.statusCode, 200)
|
|
75
|
+
t.equal(body, expectAuth
|
|
76
|
+
? 'auth: Basic dGVzdDp0ZXN0aW5n'
|
|
77
|
+
: 'auth: (nothing)')
|
|
78
|
+
t.end()
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function addTests () {
|
|
84
|
+
runTest('same host and protocol',
|
|
85
|
+
redirect.from('http', 'localhost').to('http', 'localhost'),
|
|
86
|
+
true)
|
|
87
|
+
|
|
88
|
+
runTest('same host different protocol',
|
|
89
|
+
redirect.from('http', 'localhost').to('https', 'localhost'),
|
|
90
|
+
true)
|
|
91
|
+
|
|
92
|
+
runTest('different host same protocol',
|
|
93
|
+
redirect.from('https', '127.0.0.1').to('https', 'localhost'),
|
|
94
|
+
false)
|
|
95
|
+
|
|
96
|
+
runTest('different host and protocol',
|
|
97
|
+
redirect.from('http', 'localhost').to('https', '127.0.0.1'),
|
|
98
|
+
false)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
tape('setup', function (t) {
|
|
102
|
+
s.listen(0, function () {
|
|
103
|
+
ss.listen(0, function () {
|
|
104
|
+
addTests()
|
|
105
|
+
tape('cleanup', function (t) {
|
|
106
|
+
s.destroy(function () {
|
|
107
|
+
ss.destroy(function () {
|
|
108
|
+
t.end()
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
})
|
|
112
|
+
t.end()
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
tape('redirect URL helper', function (t) {
|
|
118
|
+
t.deepEqual(
|
|
119
|
+
redirect.from('http', 'localhost').to('https', '127.0.0.1'),
|
|
120
|
+
{
|
|
121
|
+
src: util.format('http://localhost:%d/to/https/127.0.0.1', s.port),
|
|
122
|
+
dst: util.format('https://127.0.0.1:%d/from/http/localhost', ss.port)
|
|
123
|
+
})
|
|
124
|
+
t.deepEqual(
|
|
125
|
+
redirect.from('https', 'localhost').to('http', 'localhost'),
|
|
126
|
+
{
|
|
127
|
+
src: util.format('https://localhost:%d/to/http/localhost', ss.port),
|
|
128
|
+
dst: util.format('http://localhost:%d/from/https/localhost', s.port)
|
|
129
|
+
})
|
|
130
|
+
t.end()
|
|
131
|
+
})
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
var server = require('./server')
|
|
4
|
+
var request = require('../index')
|
|
5
|
+
var events = require('events')
|
|
6
|
+
var tape = require('tape')
|
|
7
|
+
var destroyable = require('server-destroy')
|
|
8
|
+
|
|
9
|
+
var s = server.createServer()
|
|
10
|
+
var ss = server.createSSLServer()
|
|
11
|
+
var e = new events.EventEmitter()
|
|
12
|
+
|
|
13
|
+
destroyable(s)
|
|
14
|
+
destroyable(ss)
|
|
15
|
+
|
|
16
|
+
function bouncy (s, serverUrl) {
|
|
17
|
+
var redirs = {
|
|
18
|
+
a: 'b',
|
|
19
|
+
b: 'c',
|
|
20
|
+
c: 'd',
|
|
21
|
+
d: 'e',
|
|
22
|
+
e: 'f',
|
|
23
|
+
f: 'g',
|
|
24
|
+
g: 'h',
|
|
25
|
+
h: 'end'
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var perm = true
|
|
29
|
+
Object.keys(redirs).forEach(function (p) {
|
|
30
|
+
var t = redirs[p]
|
|
31
|
+
|
|
32
|
+
// switch type each time
|
|
33
|
+
var type = perm ? 301 : 302
|
|
34
|
+
perm = !perm
|
|
35
|
+
s.on('/' + p, function (req, res) {
|
|
36
|
+
setTimeout(function () {
|
|
37
|
+
res.writeHead(type, { location: serverUrl + '/' + t })
|
|
38
|
+
res.end()
|
|
39
|
+
}, Math.round(Math.random() * 25))
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
s.on('/end', function (req, res) {
|
|
44
|
+
var key = req.headers['x-test-key']
|
|
45
|
+
e.emit('hit-' + key, key)
|
|
46
|
+
res.writeHead(200)
|
|
47
|
+
res.end(key)
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
tape('setup', function (t) {
|
|
52
|
+
s.listen(0, function () {
|
|
53
|
+
ss.listen(0, function () {
|
|
54
|
+
bouncy(s, ss.url)
|
|
55
|
+
bouncy(ss, s.url)
|
|
56
|
+
t.end()
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
tape('lots of redirects', function (t) {
|
|
62
|
+
var n = 10
|
|
63
|
+
t.plan(n * 4)
|
|
64
|
+
|
|
65
|
+
function doRedirect (i) {
|
|
66
|
+
var key = 'test_' + i
|
|
67
|
+
request({
|
|
68
|
+
url: (i % 2 ? s.url : ss.url) + '/a',
|
|
69
|
+
headers: { 'x-test-key': key },
|
|
70
|
+
rejectUnauthorized: false
|
|
71
|
+
}, function (err, res, body) {
|
|
72
|
+
t.equal(err, null)
|
|
73
|
+
t.equal(res.statusCode, 200)
|
|
74
|
+
t.equal(body, key)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
e.once('hit-' + key, function (v) {
|
|
78
|
+
t.equal(v, key)
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
for (var i = 0; i < n; i++) {
|
|
83
|
+
doRedirect(i)
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
tape('cleanup', function (t) {
|
|
88
|
+
s.destroy(function () {
|
|
89
|
+
ss.destroy(function () {
|
|
90
|
+
t.end()
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
})
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
var server = require('./server')
|
|
4
|
+
var assert = require('assert')
|
|
5
|
+
var request = require('../index')
|
|
6
|
+
var tape = require('tape')
|
|
7
|
+
var http = require('http')
|
|
8
|
+
var destroyable = require('server-destroy')
|
|
9
|
+
|
|
10
|
+
var s = server.createServer()
|
|
11
|
+
var ss = server.createSSLServer()
|
|
12
|
+
var hits = {}
|
|
13
|
+
var jar = request.jar()
|
|
14
|
+
|
|
15
|
+
destroyable(s)
|
|
16
|
+
destroyable(ss)
|
|
17
|
+
|
|
18
|
+
s.on('/ssl', function (req, res) {
|
|
19
|
+
res.writeHead(302, {
|
|
20
|
+
location: ss.url + '/'
|
|
21
|
+
})
|
|
22
|
+
res.end()
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
ss.on('/', function (req, res) {
|
|
26
|
+
res.writeHead(200)
|
|
27
|
+
res.end('SSL')
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
function createRedirectEndpoint (code, label, landing) {
|
|
31
|
+
s.on('/' + label, function (req, res) {
|
|
32
|
+
hits[label] = true
|
|
33
|
+
res.writeHead(code, {
|
|
34
|
+
'location': s.url + '/' + landing,
|
|
35
|
+
'set-cookie': 'ham=eggs'
|
|
36
|
+
})
|
|
37
|
+
res.end()
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function createLandingEndpoint (landing) {
|
|
42
|
+
s.on('/' + landing, function (req, res) {
|
|
43
|
+
// Make sure the cookie doesn't get included twice, see #139:
|
|
44
|
+
// Make sure cookies are set properly after redirect
|
|
45
|
+
assert.equal(req.headers.cookie, 'foo=bar; quux=baz; ham=eggs')
|
|
46
|
+
hits[landing] = true
|
|
47
|
+
res.writeHead(200, {'x-response': req.method.toUpperCase() + ' ' + landing})
|
|
48
|
+
res.end(req.method.toUpperCase() + ' ' + landing)
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function bouncer (code, label, hops) {
|
|
53
|
+
var hop
|
|
54
|
+
var landing = label + '_landing'
|
|
55
|
+
var currentLabel
|
|
56
|
+
var currentLanding
|
|
57
|
+
|
|
58
|
+
hops = hops || 1
|
|
59
|
+
|
|
60
|
+
if (hops === 1) {
|
|
61
|
+
createRedirectEndpoint(code, label, landing)
|
|
62
|
+
} else {
|
|
63
|
+
for (hop = 0; hop < hops; hop++) {
|
|
64
|
+
currentLabel = (hop === 0) ? label : label + '_' + (hop + 1)
|
|
65
|
+
currentLanding = (hop === hops - 1) ? landing : label + '_' + (hop + 2)
|
|
66
|
+
|
|
67
|
+
createRedirectEndpoint(code, currentLabel, currentLanding)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
createLandingEndpoint(landing)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
tape('setup', function (t) {
|
|
75
|
+
s.listen(0, function () {
|
|
76
|
+
ss.listen(0, function () {
|
|
77
|
+
bouncer(301, 'temp')
|
|
78
|
+
bouncer(301, 'double', 2)
|
|
79
|
+
bouncer(301, 'treble', 3)
|
|
80
|
+
bouncer(302, 'perm')
|
|
81
|
+
bouncer(302, 'nope')
|
|
82
|
+
bouncer(307, 'fwd')
|
|
83
|
+
t.end()
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
tape('permanent bounce', function (t) {
|
|
89
|
+
jar.setCookie('quux=baz', s.url)
|
|
90
|
+
hits = {}
|
|
91
|
+
request({
|
|
92
|
+
uri: s.url + '/perm',
|
|
93
|
+
jar: jar,
|
|
94
|
+
headers: { cookie: 'foo=bar' }
|
|
95
|
+
}, function (err, res, body) {
|
|
96
|
+
t.equal(err, null)
|
|
97
|
+
t.equal(res.statusCode, 200)
|
|
98
|
+
t.ok(hits.perm, 'Original request is to /perm')
|
|
99
|
+
t.ok(hits.perm_landing, 'Forward to permanent landing URL')
|
|
100
|
+
t.equal(body, 'GET perm_landing', 'Got permanent landing content')
|
|
101
|
+
t.end()
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
tape('preserve HEAD method when using followAllRedirects', function (t) {
|
|
106
|
+
jar.setCookie('quux=baz', s.url)
|
|
107
|
+
hits = {}
|
|
108
|
+
request({
|
|
109
|
+
method: 'HEAD',
|
|
110
|
+
uri: s.url + '/perm',
|
|
111
|
+
followAllRedirects: true,
|
|
112
|
+
jar: jar,
|
|
113
|
+
headers: { cookie: 'foo=bar' }
|
|
114
|
+
}, function (err, res, body) {
|
|
115
|
+
t.equal(err, null)
|
|
116
|
+
t.equal(res.statusCode, 200)
|
|
117
|
+
t.ok(hits.perm, 'Original request is to /perm')
|
|
118
|
+
t.ok(hits.perm_landing, 'Forward to permanent landing URL')
|
|
119
|
+
t.equal(res.headers['x-response'], 'HEAD perm_landing', 'Got permanent landing content')
|
|
120
|
+
t.end()
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
tape('temporary bounce', function (t) {
|
|
125
|
+
hits = {}
|
|
126
|
+
request({
|
|
127
|
+
uri: s.url + '/temp',
|
|
128
|
+
jar: jar,
|
|
129
|
+
headers: { cookie: 'foo=bar' }
|
|
130
|
+
}, function (err, res, body) {
|
|
131
|
+
t.equal(err, null)
|
|
132
|
+
t.equal(res.statusCode, 200)
|
|
133
|
+
t.ok(hits.temp, 'Original request is to /temp')
|
|
134
|
+
t.ok(hits.temp_landing, 'Forward to temporary landing URL')
|
|
135
|
+
t.equal(body, 'GET temp_landing', 'Got temporary landing content')
|
|
136
|
+
t.end()
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
tape('prevent bouncing', function (t) {
|
|
141
|
+
hits = {}
|
|
142
|
+
request({
|
|
143
|
+
uri: s.url + '/nope',
|
|
144
|
+
jar: jar,
|
|
145
|
+
headers: { cookie: 'foo=bar' },
|
|
146
|
+
followRedirect: false
|
|
147
|
+
}, function (err, res, body) {
|
|
148
|
+
t.equal(err, null)
|
|
149
|
+
t.equal(res.statusCode, 302)
|
|
150
|
+
t.ok(hits.nope, 'Original request to /nope')
|
|
151
|
+
t.ok(!hits.nope_landing, 'No chasing the redirect')
|
|
152
|
+
t.equal(res.statusCode, 302, 'Response is the bounce itself')
|
|
153
|
+
t.end()
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
tape('should not follow post redirects by default', function (t) {
|
|
158
|
+
hits = {}
|
|
159
|
+
request.post(s.url + '/temp', {
|
|
160
|
+
jar: jar,
|
|
161
|
+
headers: { cookie: 'foo=bar' }
|
|
162
|
+
}, function (err, res, body) {
|
|
163
|
+
t.equal(err, null)
|
|
164
|
+
t.equal(res.statusCode, 301)
|
|
165
|
+
t.ok(hits.temp, 'Original request is to /temp')
|
|
166
|
+
t.ok(!hits.temp_landing, 'No chasing the redirect when post')
|
|
167
|
+
t.equal(res.statusCode, 301, 'Response is the bounce itself')
|
|
168
|
+
t.end()
|
|
169
|
+
})
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
tape('should follow post redirects when followallredirects true', function (t) {
|
|
173
|
+
hits = {}
|
|
174
|
+
request.post({
|
|
175
|
+
uri: s.url + '/temp',
|
|
176
|
+
followAllRedirects: true,
|
|
177
|
+
jar: jar,
|
|
178
|
+
headers: { cookie: 'foo=bar' }
|
|
179
|
+
}, function (err, res, body) {
|
|
180
|
+
t.equal(err, null)
|
|
181
|
+
t.equal(res.statusCode, 200)
|
|
182
|
+
t.ok(hits.temp, 'Original request is to /temp')
|
|
183
|
+
t.ok(hits.temp_landing, 'Forward to temporary landing URL')
|
|
184
|
+
t.equal(body, 'GET temp_landing', 'Got temporary landing content')
|
|
185
|
+
t.end()
|
|
186
|
+
})
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
tape('should follow post redirects when followallredirects true and followOriginalHttpMethod is enabled', function (t) {
|
|
190
|
+
hits = {}
|
|
191
|
+
request.post({
|
|
192
|
+
uri: s.url + '/temp',
|
|
193
|
+
followAllRedirects: true,
|
|
194
|
+
followOriginalHttpMethod: true,
|
|
195
|
+
jar: jar,
|
|
196
|
+
headers: { cookie: 'foo=bar' }
|
|
197
|
+
}, function (err, res, body) {
|
|
198
|
+
t.equal(err, null)
|
|
199
|
+
t.equal(res.statusCode, 200)
|
|
200
|
+
t.ok(hits.temp, 'Original request is to /temp')
|
|
201
|
+
t.ok(hits.temp_landing, 'Forward to temporary landing URL')
|
|
202
|
+
t.equal(body, 'POST temp_landing', 'Got temporary landing content')
|
|
203
|
+
t.end()
|
|
204
|
+
})
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
tape('should not follow post redirects when followallredirects false', function (t) {
|
|
208
|
+
hits = {}
|
|
209
|
+
request.post({
|
|
210
|
+
uri: s.url + '/temp',
|
|
211
|
+
followAllRedirects: false,
|
|
212
|
+
jar: jar,
|
|
213
|
+
headers: { cookie: 'foo=bar' }
|
|
214
|
+
}, function (err, res, body) {
|
|
215
|
+
t.equal(err, null)
|
|
216
|
+
t.equal(res.statusCode, 301)
|
|
217
|
+
t.ok(hits.temp, 'Original request is to /temp')
|
|
218
|
+
t.ok(!hits.temp_landing, 'No chasing the redirect')
|
|
219
|
+
t.equal(res.statusCode, 301, 'Response is the bounce itself')
|
|
220
|
+
t.end()
|
|
221
|
+
})
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
tape('should not follow delete redirects by default', function (t) {
|
|
225
|
+
hits = {}
|
|
226
|
+
request.del(s.url + '/temp', {
|
|
227
|
+
jar: jar,
|
|
228
|
+
headers: { cookie: 'foo=bar' }
|
|
229
|
+
}, function (err, res, body) {
|
|
230
|
+
t.equal(err, null)
|
|
231
|
+
t.ok(res.statusCode >= 301 && res.statusCode < 400, 'Status is a redirect')
|
|
232
|
+
t.ok(hits.temp, 'Original request is to /temp')
|
|
233
|
+
t.ok(!hits.temp_landing, 'No chasing the redirect when delete')
|
|
234
|
+
t.equal(res.statusCode, 301, 'Response is the bounce itself')
|
|
235
|
+
t.end()
|
|
236
|
+
})
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
tape('should not follow delete redirects even if followredirect is set to true', function (t) {
|
|
240
|
+
hits = {}
|
|
241
|
+
request.del(s.url + '/temp', {
|
|
242
|
+
followRedirect: true,
|
|
243
|
+
jar: jar,
|
|
244
|
+
headers: { cookie: 'foo=bar' }
|
|
245
|
+
}, function (err, res, body) {
|
|
246
|
+
t.equal(err, null)
|
|
247
|
+
t.equal(res.statusCode, 301)
|
|
248
|
+
t.ok(hits.temp, 'Original request is to /temp')
|
|
249
|
+
t.ok(!hits.temp_landing, 'No chasing the redirect when delete')
|
|
250
|
+
t.equal(res.statusCode, 301, 'Response is the bounce itself')
|
|
251
|
+
t.end()
|
|
252
|
+
})
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
tape('should follow delete redirects when followallredirects true', function (t) {
|
|
256
|
+
hits = {}
|
|
257
|
+
request.del(s.url + '/temp', {
|
|
258
|
+
followAllRedirects: true,
|
|
259
|
+
jar: jar,
|
|
260
|
+
headers: { cookie: 'foo=bar' }
|
|
261
|
+
}, function (err, res, body) {
|
|
262
|
+
t.equal(err, null)
|
|
263
|
+
t.equal(res.statusCode, 200)
|
|
264
|
+
t.ok(hits.temp, 'Original request is to /temp')
|
|
265
|
+
t.ok(hits.temp_landing, 'Forward to temporary landing URL')
|
|
266
|
+
t.equal(body, 'GET temp_landing', 'Got temporary landing content')
|
|
267
|
+
t.end()
|
|
268
|
+
})
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
tape('should follow 307 delete redirects when followallredirects true', function (t) {
|
|
272
|
+
hits = {}
|
|
273
|
+
request.del(s.url + '/fwd', {
|
|
274
|
+
followAllRedirects: true,
|
|
275
|
+
jar: jar,
|
|
276
|
+
headers: { cookie: 'foo=bar' }
|
|
277
|
+
}, function (err, res, body) {
|
|
278
|
+
t.equal(err, null)
|
|
279
|
+
t.equal(res.statusCode, 200)
|
|
280
|
+
t.ok(hits.fwd, 'Original request is to /fwd')
|
|
281
|
+
t.ok(hits.fwd_landing, 'Forward to temporary landing URL')
|
|
282
|
+
t.equal(body, 'DELETE fwd_landing', 'Got temporary landing content')
|
|
283
|
+
t.end()
|
|
284
|
+
})
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
tape('double bounce', function (t) {
|
|
288
|
+
hits = {}
|
|
289
|
+
request({
|
|
290
|
+
uri: s.url + '/double',
|
|
291
|
+
jar: jar,
|
|
292
|
+
headers: { cookie: 'foo=bar' }
|
|
293
|
+
}, function (err, res, body) {
|
|
294
|
+
t.equal(err, null)
|
|
295
|
+
t.equal(res.statusCode, 200)
|
|
296
|
+
t.ok(hits.double, 'Original request is to /double')
|
|
297
|
+
t.ok(hits.double_2, 'Forward to temporary landing URL')
|
|
298
|
+
t.ok(hits.double_landing, 'Forward to landing URL')
|
|
299
|
+
t.equal(body, 'GET double_landing', 'Got temporary landing content')
|
|
300
|
+
t.end()
|
|
301
|
+
})
|
|
302
|
+
})
|
|
303
|
+
|
|
304
|
+
tape('double bounce terminated after first redirect', function (t) {
|
|
305
|
+
function filterDouble (response) {
|
|
306
|
+
return (response.headers.location || '').indexOf('double_2') === -1
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
hits = {}
|
|
310
|
+
request({
|
|
311
|
+
uri: s.url + '/double',
|
|
312
|
+
jar: jar,
|
|
313
|
+
headers: { cookie: 'foo=bar' },
|
|
314
|
+
followRedirect: filterDouble
|
|
315
|
+
}, function (err, res, body) {
|
|
316
|
+
t.equal(err, null)
|
|
317
|
+
t.equal(res.statusCode, 301)
|
|
318
|
+
t.ok(hits.double, 'Original request is to /double')
|
|
319
|
+
t.equal(res.headers.location, s.url + '/double_2', 'Current location should be ' + s.url + '/double_2')
|
|
320
|
+
t.end()
|
|
321
|
+
})
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
tape('triple bounce terminated after second redirect', function (t) {
|
|
325
|
+
function filterTreble (response) {
|
|
326
|
+
return (response.headers.location || '').indexOf('treble_3') === -1
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
hits = {}
|
|
330
|
+
request({
|
|
331
|
+
uri: s.url + '/treble',
|
|
332
|
+
jar: jar,
|
|
333
|
+
headers: { cookie: 'foo=bar' },
|
|
334
|
+
followRedirect: filterTreble
|
|
335
|
+
}, function (err, res, body) {
|
|
336
|
+
t.equal(err, null)
|
|
337
|
+
t.equal(res.statusCode, 301)
|
|
338
|
+
t.ok(hits.treble, 'Original request is to /treble')
|
|
339
|
+
t.equal(res.headers.location, s.url + '/treble_3', 'Current location should be ' + s.url + '/treble_3')
|
|
340
|
+
t.end()
|
|
341
|
+
})
|
|
342
|
+
})
|
|
343
|
+
|
|
344
|
+
tape('http to https redirect', function (t) {
|
|
345
|
+
hits = {}
|
|
346
|
+
request.get({
|
|
347
|
+
uri: require('url').parse(s.url + '/ssl'),
|
|
348
|
+
rejectUnauthorized: false
|
|
349
|
+
}, function (err, res, body) {
|
|
350
|
+
t.equal(err, null)
|
|
351
|
+
t.equal(res.statusCode, 200)
|
|
352
|
+
t.equal(body, 'SSL', 'Got SSL redirect')
|
|
353
|
+
t.end()
|
|
354
|
+
})
|
|
355
|
+
})
|
|
356
|
+
|
|
357
|
+
tape('should have referer header by default when following redirect', function (t) {
|
|
358
|
+
request.post({
|
|
359
|
+
uri: s.url + '/temp',
|
|
360
|
+
jar: jar,
|
|
361
|
+
followAllRedirects: true,
|
|
362
|
+
headers: { cookie: 'foo=bar' }
|
|
363
|
+
}, function (err, res, body) {
|
|
364
|
+
t.equal(err, null)
|
|
365
|
+
t.equal(res.statusCode, 200)
|
|
366
|
+
t.end()
|
|
367
|
+
})
|
|
368
|
+
.on('redirect', function () {
|
|
369
|
+
t.equal(this.headers.referer, s.url + '/temp')
|
|
370
|
+
})
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
tape('should not have referer header when removeRefererHeader is true', function (t) {
|
|
374
|
+
request.post({
|
|
375
|
+
uri: s.url + '/temp',
|
|
376
|
+
jar: jar,
|
|
377
|
+
followAllRedirects: true,
|
|
378
|
+
removeRefererHeader: true,
|
|
379
|
+
headers: { cookie: 'foo=bar' }
|
|
380
|
+
}, function (err, res, body) {
|
|
381
|
+
t.equal(err, null)
|
|
382
|
+
t.equal(res.statusCode, 200)
|
|
383
|
+
t.end()
|
|
384
|
+
})
|
|
385
|
+
.on('redirect', function () {
|
|
386
|
+
t.equal(this.headers.referer, undefined)
|
|
387
|
+
})
|
|
388
|
+
})
|
|
389
|
+
|
|
390
|
+
tape('should preserve referer header set in the initial request when removeRefererHeader is true', function (t) {
|
|
391
|
+
request.post({
|
|
392
|
+
uri: s.url + '/temp',
|
|
393
|
+
jar: jar,
|
|
394
|
+
followAllRedirects: true,
|
|
395
|
+
removeRefererHeader: true,
|
|
396
|
+
headers: { cookie: 'foo=bar', referer: 'http://awesome.com' }
|
|
397
|
+
}, function (err, res, body) {
|
|
398
|
+
t.equal(err, null)
|
|
399
|
+
t.equal(res.statusCode, 200)
|
|
400
|
+
t.end()
|
|
401
|
+
})
|
|
402
|
+
.on('redirect', function () {
|
|
403
|
+
t.equal(this.headers.referer, 'http://awesome.com')
|
|
404
|
+
})
|
|
405
|
+
})
|
|
406
|
+
|
|
407
|
+
tape('should use same agent class on redirect', function (t) {
|
|
408
|
+
var agent
|
|
409
|
+
var calls = 0
|
|
410
|
+
var agentOptions = {}
|
|
411
|
+
|
|
412
|
+
function FakeAgent (agentOptions) {
|
|
413
|
+
var createConnection
|
|
414
|
+
|
|
415
|
+
agent = new http.Agent(agentOptions)
|
|
416
|
+
createConnection = agent.createConnection
|
|
417
|
+
agent.createConnection = function () {
|
|
418
|
+
calls++
|
|
419
|
+
return createConnection.apply(agent, arguments)
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return agent
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
hits = {}
|
|
426
|
+
request.get({
|
|
427
|
+
uri: s.url + '/temp',
|
|
428
|
+
jar: jar,
|
|
429
|
+
headers: { cookie: 'foo=bar' },
|
|
430
|
+
agentOptions: agentOptions,
|
|
431
|
+
agentClass: FakeAgent
|
|
432
|
+
}, function (err, res, body) {
|
|
433
|
+
t.equal(err, null)
|
|
434
|
+
t.equal(res.statusCode, 200)
|
|
435
|
+
t.equal(body, 'GET temp_landing', 'Got temporary landing content')
|
|
436
|
+
t.equal(calls, 2)
|
|
437
|
+
t.ok(this.agent === agent, 'Reinstantiated the user-specified agent')
|
|
438
|
+
t.ok(this.agentOptions === agentOptions, 'Reused agent options')
|
|
439
|
+
t.end()
|
|
440
|
+
})
|
|
441
|
+
})
|
|
442
|
+
|
|
443
|
+
tape('cleanup', function (t) {
|
|
444
|
+
s.destroy(function () {
|
|
445
|
+
ss.destroy(function () {
|
|
446
|
+
t.end()
|
|
447
|
+
})
|
|
448
|
+
})
|
|
449
|
+
})
|