@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,120 @@
1
+ 'use strict'
2
+
3
+ var http = require('http')
4
+ var request = require('../index')
5
+ var tape = require('tape')
6
+
7
+ var s = http.createServer(function (req, res) {
8
+ res.statusCode = 200
9
+ res.end('ok')
10
+ })
11
+
12
+ tape('setup', function (t) {
13
+ s.listen(0, function () {
14
+ s.port = this.address().port
15
+ s.url = 'http://localhost:' + s.port
16
+ t.end()
17
+ })
18
+ })
19
+
20
+ tape('lowercase', function (t) {
21
+ request(s.url, function (err, resp, body) {
22
+ t.equal(err, null)
23
+ t.equal(body, 'ok')
24
+ t.end()
25
+ })
26
+ })
27
+
28
+ tape('uppercase', function (t) {
29
+ request(s.url.replace('http', 'HTTP'), function (err, resp, body) {
30
+ t.equal(err, null)
31
+ t.equal(body, 'ok')
32
+ t.end()
33
+ })
34
+ })
35
+
36
+ tape('mixedcase', function (t) {
37
+ request(s.url.replace('http', 'HtTp'), function (err, resp, body) {
38
+ t.equal(err, null)
39
+ t.equal(body, 'ok')
40
+ t.end()
41
+ })
42
+ })
43
+
44
+ tape('hostname and port', function (t) {
45
+ request({
46
+ uri: {
47
+ protocol: 'http:',
48
+ hostname: 'localhost',
49
+ port: s.port
50
+ }
51
+ }, function (err, res, body) {
52
+ t.equal(err, null)
53
+ t.equal(body, 'ok')
54
+ t.end()
55
+ })
56
+ })
57
+
58
+ tape('hostname and port 1', function (t) {
59
+ request({
60
+ uri: {
61
+ protocol: 'http:',
62
+ hostname: 'localhost',
63
+ port: s.port
64
+ }
65
+ }, function (err, res, body) {
66
+ t.equal(err, null)
67
+ t.equal(body, 'ok')
68
+ t.end()
69
+ })
70
+ })
71
+
72
+ tape('hostname and port 2', function (t) {
73
+ request({
74
+ protocol: 'http:',
75
+ hostname: 'localhost',
76
+ port: s.port
77
+ }, {
78
+ // need this empty options object, otherwise request thinks no uri was set
79
+ }, function (err, res, body) {
80
+ t.equal(err, null)
81
+ t.equal(body, 'ok')
82
+ t.end()
83
+ })
84
+ })
85
+
86
+ tape('hostname and port 3', function (t) {
87
+ request({
88
+ protocol: 'http:',
89
+ hostname: 'localhost',
90
+ port: s.port
91
+ }, function (err, res, body) {
92
+ t.notEqual(err, null)
93
+ t.equal(err.message, 'options.uri is a required argument')
94
+ t.equal(body, undefined)
95
+ t.end()
96
+ })
97
+ })
98
+
99
+ tape('hostname and query string', function (t) {
100
+ request({
101
+ uri: {
102
+ protocol: 'http:',
103
+ hostname: 'localhost',
104
+ port: s.port
105
+ },
106
+ qs: {
107
+ test: 'test'
108
+ }
109
+ }, function (err, res, body) {
110
+ t.equal(err, null)
111
+ t.equal(body, 'ok')
112
+ t.end()
113
+ })
114
+ })
115
+
116
+ tape('cleanup', function (t) {
117
+ s.close(function () {
118
+ t.end()
119
+ })
120
+ })
@@ -0,0 +1,117 @@
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
+ tape('setup', function (t) {
10
+ s.listen(0, function () {
11
+ t.end()
12
+ })
13
+ })
14
+
15
+ function testJSONValue (testId, value) {
16
+ tape('test ' + testId, function (t) {
17
+ var testUrl = '/' + testId
18
+ s.on(testUrl, server.createPostJSONValidator(value, 'application/json'))
19
+ var opts = {
20
+ method: 'PUT',
21
+ uri: s.url + testUrl,
22
+ json: true,
23
+ body: value
24
+ }
25
+ request(opts, function (err, resp, body) {
26
+ t.equal(err, null)
27
+ t.equal(resp.statusCode, 200)
28
+ t.deepEqual(body, value)
29
+ t.end()
30
+ })
31
+ })
32
+ }
33
+
34
+ function testJSONValueReviver (testId, value, reviver, revivedValue) {
35
+ tape('test ' + testId, function (t) {
36
+ var testUrl = '/' + testId
37
+ s.on(testUrl, server.createPostJSONValidator(value, 'application/json'))
38
+ var opts = {
39
+ method: 'PUT',
40
+ uri: s.url + testUrl,
41
+ json: true,
42
+ jsonReviver: reviver,
43
+ body: value
44
+ }
45
+ request(opts, function (err, resp, body) {
46
+ t.equal(err, null)
47
+ t.equal(resp.statusCode, 200)
48
+ t.deepEqual(body, revivedValue)
49
+ t.end()
50
+ })
51
+ })
52
+ }
53
+
54
+ function testJSONValueReplacer (testId, value, replacer, replacedValue) {
55
+ tape('test ' + testId, function (t) {
56
+ var testUrl = '/' + testId
57
+ s.on(testUrl, server.createPostJSONValidator(replacedValue, 'application/json'))
58
+ var opts = {
59
+ method: 'PUT',
60
+ uri: s.url + testUrl,
61
+ json: true,
62
+ jsonReplacer: replacer,
63
+ body: value
64
+ }
65
+ request(opts, function (err, resp, body) {
66
+ t.equal(err, null)
67
+ t.equal(resp.statusCode, 200)
68
+ t.deepEqual(body, replacedValue)
69
+ t.end()
70
+ })
71
+ })
72
+ }
73
+
74
+ testJSONValue('jsonNull', null)
75
+ testJSONValue('jsonTrue', true)
76
+ testJSONValue('jsonFalse', false)
77
+ testJSONValue('jsonNumber', -289365.2938)
78
+ testJSONValue('jsonString', 'some string')
79
+ testJSONValue('jsonArray', ['value1', 2, null, 8925.53289, true, false, ['array'], { object: 'property' }])
80
+ testJSONValue('jsonObject', {
81
+ trueProperty: true,
82
+ falseProperty: false,
83
+ numberProperty: -98346.34698,
84
+ stringProperty: 'string',
85
+ nullProperty: null,
86
+ arrayProperty: ['array'],
87
+ objectProperty: { object: 'property' }
88
+ })
89
+
90
+ testJSONValueReviver('jsonReviver', -48269.592, function (k, v) {
91
+ return v * -1
92
+ }, 48269.592)
93
+ testJSONValueReviver('jsonReviverInvalid', -48269.592, 'invalid reviver', -48269.592)
94
+
95
+ testJSONValueReplacer('jsonReplacer', -48269.592, function (k, v) {
96
+ return v * -1
97
+ }, 48269.592)
98
+ testJSONValueReplacer('jsonReplacerInvalid', -48269.592, 'invalid replacer', -48269.592)
99
+ testJSONValueReplacer('jsonReplacerObject', {foo: 'bar'}, function (k, v) {
100
+ return v.toUpperCase ? v.toUpperCase() : v
101
+ }, {foo: 'BAR'})
102
+
103
+ tape('missing body', function (t) {
104
+ s.on('/missing-body', function (req, res) {
105
+ t.equal(req.headers['content-type'], undefined)
106
+ res.end()
107
+ })
108
+ request({url: s.url + '/missing-body', json: true}, function () {
109
+ t.end()
110
+ })
111
+ })
112
+
113
+ tape('cleanup', function (t) {
114
+ s.close(function () {
115
+ t.end()
116
+ })
117
+ })
@@ -0,0 +1,49 @@
1
+ 'use strict'
2
+ var request = require('../index')
3
+ var tape = require('tape')
4
+
5
+ tape('bind to invalid address', function (t) {
6
+ request.get({
7
+ uri: 'http://www.google.com',
8
+ localAddress: '1.2.3.4'
9
+ }, function (err, res) {
10
+ t.notEqual(err, null)
11
+ t.equal(true, /bind EADDRNOTAVAIL/.test(err.message))
12
+ t.equal(res, undefined)
13
+ t.end()
14
+ })
15
+ })
16
+
17
+ tape('bind to local address', function (t) {
18
+ request.get({
19
+ uri: 'http://www.google.com',
20
+ localAddress: '127.0.0.1'
21
+ }, function (err, res) {
22
+ t.notEqual(err, null)
23
+ t.equal(res, undefined)
24
+ t.end()
25
+ })
26
+ })
27
+
28
+ tape('bind to local address on redirect', function (t) {
29
+ var os = require('os')
30
+ var localInterfaces = os.networkInterfaces()
31
+ var localIPS = []
32
+ Object.keys(localInterfaces).forEach(function (ifname) {
33
+ localInterfaces[ifname].forEach(function (iface) {
34
+ if (iface.family !== 'IPv4' || iface.internal !== false) {
35
+ // skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses
36
+ return
37
+ }
38
+ localIPS.push(iface.address)
39
+ })
40
+ })
41
+ request.get({
42
+ uri: 'http://google.com', // redirects to 'http://google.com'
43
+ localAddress: localIPS[0]
44
+ }, function (err, res) {
45
+ t.equal(err, null)
46
+ t.equal(res.request.localAddress, localIPS[0])
47
+ t.end()
48
+ })
49
+ })
@@ -0,0 +1,147 @@
1
+ 'use strict'
2
+
3
+ var http = require('http')
4
+ var path = require('path')
5
+ var request = require('../index')
6
+ var fs = require('fs')
7
+ var tape = require('tape')
8
+
9
+ var localFile = path.join(__dirname, 'unicycle.jpg')
10
+ var cases = {
11
+ // based on body type
12
+ '+array -stream': {
13
+ options: {
14
+ multipart: [{name: 'field', body: 'value'}]
15
+ },
16
+ expected: {chunked: false}
17
+ },
18
+ '+array +stream': {
19
+ options: {
20
+ multipart: [{name: 'file', body: null}]
21
+ },
22
+ expected: {chunked: true}
23
+ },
24
+ // encoding overrides body value
25
+ '+array +encoding': {
26
+ options: {
27
+ headers: {'transfer-encoding': 'chunked'},
28
+ multipart: [{name: 'field', body: 'value'}]
29
+ },
30
+ expected: {chunked: true}
31
+ },
32
+
33
+ // based on body type
34
+ '+object -stream': {
35
+ options: {
36
+ multipart: {data: [{name: 'field', body: 'value'}]}
37
+ },
38
+ expected: {chunked: false}
39
+ },
40
+ '+object +stream': {
41
+ options: {
42
+ multipart: {data: [{name: 'file', body: null}]}
43
+ },
44
+ expected: {chunked: true}
45
+ },
46
+ // encoding overrides body value
47
+ '+object +encoding': {
48
+ options: {
49
+ headers: {'transfer-encoding': 'chunked'},
50
+ multipart: {data: [{name: 'field', body: 'value'}]}
51
+ },
52
+ expected: {chunked: true}
53
+ },
54
+
55
+ // based on body type
56
+ '+object -chunked -stream': {
57
+ options: {
58
+ multipart: {chunked: false, data: [{name: 'field', body: 'value'}]}
59
+ },
60
+ expected: {chunked: false}
61
+ },
62
+ '+object -chunked +stream': {
63
+ options: {
64
+ multipart: {chunked: false, data: [{name: 'file', body: null}]}
65
+ },
66
+ expected: {chunked: true}
67
+ },
68
+ // chunked overrides body value
69
+ '+object +chunked -stream': {
70
+ options: {
71
+ multipart: {chunked: true, data: [{name: 'field', body: 'value'}]}
72
+ },
73
+ expected: {chunked: true}
74
+ },
75
+ // encoding overrides chunked
76
+ '+object +encoding -chunked': {
77
+ options: {
78
+ headers: {'transfer-encoding': 'chunked'},
79
+ multipart: {chunked: false, data: [{name: 'field', body: 'value'}]}
80
+ },
81
+ expected: {chunked: true}
82
+ }
83
+ }
84
+
85
+ function runTest (t, test) {
86
+ var server = http.createServer(function (req, res) {
87
+ t.ok(req.headers['content-type'].match(/^multipart\/related; boundary=[^\s;]+$/))
88
+
89
+ if (test.expected.chunked) {
90
+ t.ok(req.headers['transfer-encoding'] === 'chunked')
91
+ t.notOk(req.headers['content-length'])
92
+ } else {
93
+ t.ok(req.headers['content-length'])
94
+ t.notOk(req.headers['transfer-encoding'])
95
+ }
96
+
97
+ // temp workaround
98
+ var data = ''
99
+ req.setEncoding('utf8')
100
+
101
+ req.on('data', function (d) {
102
+ data += d
103
+ })
104
+
105
+ req.on('end', function () {
106
+ // check for the fields traces
107
+ if (test.expected.chunked && data.indexOf('name: file') !== -1) {
108
+ // file
109
+ t.ok(data.indexOf('name: file') !== -1)
110
+ // check for unicycle.jpg traces
111
+ t.ok(data.indexOf('2005:06:21 01:44:12') !== -1)
112
+ } else {
113
+ // field
114
+ t.ok(data.indexOf('name: field') !== -1)
115
+ var parts = test.options.multipart.data || test.options.multipart
116
+ t.ok(data.indexOf(parts[0].body) !== -1)
117
+ }
118
+
119
+ res.writeHead(200)
120
+ res.end()
121
+ })
122
+ })
123
+
124
+ server.listen(0, function () {
125
+ var url = 'http://localhost:' + this.address().port
126
+ // @NOTE: multipartData properties must be set here
127
+ // so that file read stream does not leak in node v0.8
128
+ var parts = test.options.multipart.data || test.options.multipart
129
+ if (parts[0].name === 'file') {
130
+ parts[0].body = fs.createReadStream(localFile)
131
+ }
132
+
133
+ request.post(url, test.options, function (err, res, body) {
134
+ t.equal(err, null)
135
+ t.equal(res.statusCode, 200)
136
+ server.close(function () {
137
+ t.end()
138
+ })
139
+ })
140
+ })
141
+ }
142
+
143
+ Object.keys(cases).forEach(function (name) {
144
+ tape('multipart-encoding ' + name, function (t) {
145
+ runTest(t, cases[name])
146
+ })
147
+ })
@@ -0,0 +1,129 @@
1
+ 'use strict'
2
+
3
+ var http = require('http')
4
+ var path = require('path')
5
+ var request = require('../index')
6
+ var fs = require('fs')
7
+ var tape = require('tape')
8
+
9
+ function runTest (t, a) {
10
+ var remoteFile = path.join(__dirname, 'googledoodle.jpg')
11
+ var localFile = path.join(__dirname, 'unicycle.jpg')
12
+ var multipartData = []
13
+
14
+ var server = http.createServer(function (req, res) {
15
+ if (req.url === '/file') {
16
+ res.writeHead(200, {'content-type': 'image/jpg'})
17
+ res.end(fs.readFileSync(remoteFile), 'binary')
18
+ return
19
+ }
20
+
21
+ if (a.header) {
22
+ if (a.header.indexOf('mixed') !== -1) {
23
+ t.ok(req.headers['content-type'].match(/^multipart\/mixed; boundary=[^\s;]+$/))
24
+ } else {
25
+ t.ok(req.headers['content-type']
26
+ .match(/^multipart\/related; boundary=XXX; type=text\/xml; start="<root>"$/))
27
+ }
28
+ } else {
29
+ t.ok(req.headers['content-type'].match(/^multipart\/related; boundary=[^\s;]+$/))
30
+ }
31
+
32
+ // temp workaround
33
+ var data = ''
34
+ req.setEncoding('utf8')
35
+
36
+ req.on('data', function (d) {
37
+ data += d
38
+ })
39
+
40
+ req.on('end', function () {
41
+ // check for the fields traces
42
+
43
+ // my_field
44
+ t.ok(data.indexOf('name: my_field') !== -1)
45
+ t.ok(data.indexOf(multipartData[0].body) !== -1)
46
+
47
+ // my_number
48
+ t.ok(data.indexOf('name: my_number') !== -1)
49
+ t.ok(data.indexOf(multipartData[1].body) !== -1)
50
+
51
+ // my_buffer
52
+ t.ok(data.indexOf('name: my_buffer') !== -1)
53
+ t.ok(data.indexOf(multipartData[2].body) !== -1)
54
+
55
+ // my_file
56
+ t.ok(data.indexOf('name: my_file') !== -1)
57
+ // check for unicycle.jpg traces
58
+ t.ok(data.indexOf('2005:06:21 01:44:12') !== -1)
59
+
60
+ // remote_file
61
+ t.ok(data.indexOf('name: remote_file') !== -1)
62
+ // check for http://localhost:nnnn/file traces
63
+ t.ok(data.indexOf('Photoshop ICC') !== -1)
64
+
65
+ if (a.header && a.header.indexOf('boundary=XXX') !== -1) {
66
+ t.ok(data.indexOf('--XXX') !== -1)
67
+ }
68
+
69
+ res.writeHead(200)
70
+ res.end(a.json ? JSON.stringify({status: 'done'}) : 'done')
71
+ })
72
+ })
73
+
74
+ server.listen(0, function () {
75
+ var url = 'http://localhost:' + this.address().port
76
+ // @NOTE: multipartData properties must be set here so that my_file read stream does not leak in node v0.8
77
+ multipartData = [
78
+ {name: 'my_field', body: 'my_value'},
79
+ {name: 'my_number', body: 1000},
80
+ {name: 'my_buffer', body: Buffer.from([1, 2, 3])},
81
+ {name: 'my_file', body: fs.createReadStream(localFile)},
82
+ {name: 'remote_file', body: request(url + '/file')}
83
+ ]
84
+
85
+ var reqOptions = {
86
+ url: url + '/upload',
87
+ multipart: multipartData
88
+ }
89
+ if (a.header) {
90
+ reqOptions.headers = {
91
+ 'content-type': a.header
92
+ }
93
+ }
94
+ if (a.json) {
95
+ reqOptions.json = true
96
+ }
97
+ request[a.method](reqOptions, function (err, res, body) {
98
+ t.equal(err, null)
99
+ t.equal(res.statusCode, 200)
100
+ t.deepEqual(body, a.json ? {status: 'done'} : 'done')
101
+ server.close(function () {
102
+ t.end()
103
+ })
104
+ })
105
+ })
106
+ }
107
+
108
+ var testHeaders = [
109
+ null,
110
+ 'multipart/mixed',
111
+ 'multipart/related; boundary=XXX; type=text/xml; start="<root>"'
112
+ ]
113
+
114
+ var methods = ['post', 'get']
115
+ methods.forEach(function (method) {
116
+ testHeaders.forEach(function (header) {
117
+ [true, false].forEach(function (json) {
118
+ var name = [
119
+ 'multipart-related', method.toUpperCase(),
120
+ (header || 'default'),
121
+ (json ? '+' : '-') + 'json'
122
+ ].join(' ')
123
+
124
+ tape(name, function (t) {
125
+ runTest(t, {method: method, header: header, json: json})
126
+ })
127
+ })
128
+ })
129
+ })
@@ -0,0 +1,95 @@
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('')
10
+ })
11
+
12
+ var stderr = []
13
+ var prevStderrLen = 0
14
+
15
+ tape('setup', function (t) {
16
+ process.stderr._oldWrite = process.stderr.write
17
+ process.stderr.write = function (string, encoding, fd) {
18
+ stderr.push(string)
19
+ }
20
+
21
+ s.listen(0, function () {
22
+ s.url = 'http://localhost:' + this.address().port
23
+ t.end()
24
+ })
25
+ })
26
+
27
+ tape('a simple request should not fail with debugging enabled', function (t) {
28
+ request.debug = true
29
+ t.equal(request.Request.debug, true, 'request.debug sets request.Request.debug')
30
+ t.equal(request.debug, true, 'request.debug gets request.Request.debug')
31
+ stderr = []
32
+
33
+ request(s.url, function (err, res, body) {
34
+ t.ifError(err, 'the request did not fail')
35
+ t.ok(res, 'the request did not fail')
36
+
37
+ t.ok(stderr.length, 'stderr has some messages')
38
+ var url = s.url.replace(/\//g, '\\/')
39
+ var patterns = [
40
+ /^REQUEST { uri: /,
41
+ new RegExp('^REQUEST make request ' + url + '/\n$'),
42
+ /^REQUEST onRequestResponse /,
43
+ /^REQUEST finish init /,
44
+ /^REQUEST response end /,
45
+ /^REQUEST end event /,
46
+ /^REQUEST emitting complete /
47
+ ]
48
+ patterns.forEach(function (pattern) {
49
+ var found = false
50
+ stderr.forEach(function (msg) {
51
+ if (pattern.test(msg)) {
52
+ found = true
53
+ }
54
+ })
55
+ t.ok(found, 'a log message matches ' + pattern)
56
+ })
57
+ prevStderrLen = stderr.length
58
+ t.end()
59
+ })
60
+ })
61
+
62
+ tape('there should be no further lookups on process.env', function (t) {
63
+ process.env.NODE_DEBUG = ''
64
+ stderr = []
65
+
66
+ request(s.url, function (err, res, body) {
67
+ t.ifError(err, 'the request did not fail')
68
+ t.ok(res, 'the request did not fail')
69
+ t.equal(stderr.length, prevStderrLen, 'env.NODE_DEBUG is not retested')
70
+ t.end()
71
+ })
72
+ })
73
+
74
+ tape('it should be possible to disable debugging at runtime', function (t) {
75
+ request.debug = false
76
+ t.equal(request.Request.debug, false, 'request.debug sets request.Request.debug')
77
+ t.equal(request.debug, false, 'request.debug gets request.Request.debug')
78
+ stderr = []
79
+
80
+ request(s.url, function (err, res, body) {
81
+ t.ifError(err, 'the request did not fail')
82
+ t.ok(res, 'the request did not fail')
83
+ t.equal(stderr.length, 0, 'debugging can be disabled')
84
+ t.end()
85
+ })
86
+ })
87
+
88
+ tape('cleanup', function (t) {
89
+ process.stderr.write = process.stderr._oldWrite
90
+ delete process.stderr._oldWrite
91
+
92
+ s.close(function () {
93
+ t.end()
94
+ })
95
+ })