@fastify/reply-from 7.0.0

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 (88) hide show
  1. package/.github/dependabot.yml +13 -0
  2. package/.github/stale.yml +21 -0
  3. package/.github/workflows/ci.yml +60 -0
  4. package/.taprc +5 -0
  5. package/LICENSE +21 -0
  6. package/README.md +335 -0
  7. package/example.js +36 -0
  8. package/index.d.ts +99 -0
  9. package/index.js +262 -0
  10. package/lib/request.js +288 -0
  11. package/lib/utils.js +81 -0
  12. package/package.json +70 -0
  13. package/test/async-route-handler.js +50 -0
  14. package/test/base-get.js +48 -0
  15. package/test/base-path.js +38 -0
  16. package/test/base-querystring.js +48 -0
  17. package/test/build-url.js +69 -0
  18. package/test/core-with-path-in-base.js +50 -0
  19. package/test/custom-undici-instance.js +77 -0
  20. package/test/fastify-multipart-incompatibility.js +90 -0
  21. package/test/fixtures/fastify.cert +19 -0
  22. package/test/fixtures/fastify.key +27 -0
  23. package/test/fixtures/file.txt +1 -0
  24. package/test/full-get.js +45 -0
  25. package/test/full-https-get.js +55 -0
  26. package/test/full-post-extended-content-type.js +59 -0
  27. package/test/full-post-http2.js +49 -0
  28. package/test/full-post-stream-core.js +66 -0
  29. package/test/full-post-stream.js +64 -0
  30. package/test/full-post.js +56 -0
  31. package/test/full-querystring-rewrite-option-complex.js +48 -0
  32. package/test/full-querystring-rewrite-option-function.js +51 -0
  33. package/test/full-querystring-rewrite-option.js +48 -0
  34. package/test/full-querystring-rewrite-string.js +46 -0
  35. package/test/full-querystring-rewrite.js +46 -0
  36. package/test/full-querystring.js +46 -0
  37. package/test/full-rewrite-body-content-type.js +59 -0
  38. package/test/full-rewrite-body-http.js +63 -0
  39. package/test/full-rewrite-body-to-empty-string.js +61 -0
  40. package/test/full-rewrite-body-to-null.js +61 -0
  41. package/test/full-rewrite-body.js +61 -0
  42. package/test/get-upstream-http.js +70 -0
  43. package/test/get-upstream-undici.js +45 -0
  44. package/test/get-with-body.js +55 -0
  45. package/test/head-with-body.js +57 -0
  46. package/test/host-header.js +67 -0
  47. package/test/http-agents.js +55 -0
  48. package/test/http-http2.js +50 -0
  49. package/test/http-invalid-target.js +35 -0
  50. package/test/http-retry.js +109 -0
  51. package/test/http-timeout.js +56 -0
  52. package/test/http2-http2.js +57 -0
  53. package/test/http2-https.js +80 -0
  54. package/test/http2-invalid-target.js +36 -0
  55. package/test/http2-target-crash.js +53 -0
  56. package/test/http2-target-multi-crash.js +60 -0
  57. package/test/http2-timeout.js +92 -0
  58. package/test/https-agents.js +67 -0
  59. package/test/index.test-d.ts +136 -0
  60. package/test/modifyCoreObjects-false.js +48 -0
  61. package/test/no-body-opts-with-get.js +49 -0
  62. package/test/no-body-opts-with-head.js +51 -0
  63. package/test/no-stream-body-option.js +58 -0
  64. package/test/on-error.js +62 -0
  65. package/test/onResponse.js +48 -0
  66. package/test/padded-body.js +64 -0
  67. package/test/post-formbody.js +59 -0
  68. package/test/post-plain-text.js +56 -0
  69. package/test/post-with-custom-encoded-contenttype.js +65 -0
  70. package/test/retry-on-503.js +101 -0
  71. package/test/rewrite-headers.js +52 -0
  72. package/test/rewrite-request-headers.js +47 -0
  73. package/test/transform-body.js +61 -0
  74. package/test/undici-agent.js +77 -0
  75. package/test/undici-body.js +70 -0
  76. package/test/undici-options.js +73 -0
  77. package/test/undici-retry.js +109 -0
  78. package/test/undici-timeout-body-partial.js +60 -0
  79. package/test/undici-timeout-body.js +63 -0
  80. package/test/undici-timeout.js +61 -0
  81. package/test/undici-with-path-in-base.js +50 -0
  82. package/test/undici.js +50 -0
  83. package/test/unexpected-error.js +46 -0
  84. package/test/unix-http-undici-from.js +51 -0
  85. package/test/unix-http-undici.js +62 -0
  86. package/test/unix-http.js +65 -0
  87. package/test/unix-https-undici.js +71 -0
  88. package/test/unix-https.js +71 -0
@@ -0,0 +1,50 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const Fastify = require('fastify')
5
+ const From = require('..')
6
+ const http = require('http')
7
+ const get = require('simple-get').concat
8
+
9
+ const instance = Fastify()
10
+
11
+ t.plan(11)
12
+ t.teardown(instance.close.bind(instance))
13
+
14
+ const target = http.createServer((req, res) => {
15
+ t.pass('request proxied')
16
+ t.equal(req.method, 'GET')
17
+ t.equal(req.url, '/')
18
+ res.statusCode = 205
19
+ res.setHeader('Content-Type', 'text/plain')
20
+ res.setHeader('x-my-header', 'hello!')
21
+ res.end('hello world')
22
+ })
23
+
24
+ instance.get('/', async (request, reply) => {
25
+ const p = reply.from()
26
+ t.equal(p, reply)
27
+ return p
28
+ })
29
+
30
+ t.teardown(target.close.bind(target))
31
+
32
+ target.listen(0, (err) => {
33
+ t.error(err)
34
+
35
+ instance.register(From, {
36
+ base: `http://localhost:${target.address().port}`
37
+ })
38
+
39
+ instance.listen(0, (err) => {
40
+ t.error(err)
41
+
42
+ get(`http://localhost:${instance.server.address().port}`, (err, res, data) => {
43
+ t.error(err)
44
+ t.equal(res.headers['content-type'], 'text/plain')
45
+ t.equal(res.headers['x-my-header'], 'hello!')
46
+ t.equal(res.statusCode, 205)
47
+ t.equal(data.toString(), 'hello world')
48
+ })
49
+ })
50
+ })
@@ -0,0 +1,48 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const Fastify = require('fastify')
5
+ const From = require('..')
6
+ const http = require('http')
7
+ const get = require('simple-get').concat
8
+
9
+ const instance = Fastify()
10
+
11
+ t.plan(10)
12
+ t.teardown(instance.close.bind(instance))
13
+
14
+ const target = http.createServer((req, res) => {
15
+ t.pass('request proxied')
16
+ t.equal(req.method, 'GET')
17
+ t.equal(req.url, '/')
18
+ res.statusCode = 205
19
+ res.setHeader('Content-Type', 'text/plain')
20
+ res.setHeader('x-my-header', 'hello!')
21
+ res.end('hello world')
22
+ })
23
+
24
+ instance.get('/', (request, reply) => {
25
+ reply.from()
26
+ })
27
+
28
+ t.teardown(target.close.bind(target))
29
+
30
+ target.listen(0, (err) => {
31
+ t.error(err)
32
+
33
+ instance.register(From, {
34
+ base: `http://localhost:${target.address().port}`
35
+ })
36
+
37
+ instance.listen(0, (err) => {
38
+ t.error(err)
39
+
40
+ get(`http://localhost:${instance.server.address().port}`, (err, res, data) => {
41
+ t.error(err)
42
+ t.equal(res.headers['content-type'], 'text/plain')
43
+ t.equal(res.headers['x-my-header'], 'hello!')
44
+ t.equal(res.statusCode, 205)
45
+ t.equal(data.toString(), 'hello world')
46
+ })
47
+ })
48
+ })
@@ -0,0 +1,38 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const Fastify = require('fastify')
5
+ const From = require('..')
6
+ const get = require('simple-get').concat
7
+ const nock = require('nock')
8
+
9
+ const instance = Fastify()
10
+
11
+ nock('http://httpbin.org')
12
+ .get('/ip')
13
+ .reply(200, function (uri, requestBody) {
14
+ t.equal(this.req.headers.host, 'httpbin.org')
15
+ return { origin: '127.0.0.1' }
16
+ })
17
+
18
+ t.plan(6)
19
+ t.teardown(instance.close.bind(instance))
20
+
21
+ instance.get('/', (request, reply) => {
22
+ reply.from('http://httpbin.org/ip')
23
+ })
24
+
25
+ instance.register(From, {
26
+ undici: false
27
+ })
28
+
29
+ instance.listen(0, (err) => {
30
+ t.error(err)
31
+
32
+ get(`http://localhost:${instance.server.address().port}`, (err, res, data) => {
33
+ t.error(err)
34
+ t.equal(res.statusCode, 200)
35
+ t.equal(res.headers['content-type'], 'application/json')
36
+ t.equal(typeof JSON.parse(data).origin, 'string')
37
+ })
38
+ })
@@ -0,0 +1,48 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const Fastify = require('fastify')
5
+ const From = require('..')
6
+ const http = require('http')
7
+ const get = require('simple-get').concat
8
+
9
+ const instance = Fastify()
10
+
11
+ t.plan(10)
12
+ t.teardown(instance.close.bind(instance))
13
+
14
+ const target = http.createServer((req, res) => {
15
+ t.pass('request proxied')
16
+ t.equal(req.method, 'GET')
17
+ t.equal(req.url, '/hello?a=b')
18
+ res.statusCode = 205
19
+ res.setHeader('Content-Type', 'text/plain')
20
+ res.setHeader('x-my-header', 'hello!')
21
+ res.end('hello world')
22
+ })
23
+
24
+ instance.get('/hello', (request, reply) => {
25
+ reply.from()
26
+ })
27
+
28
+ t.teardown(target.close.bind(target))
29
+
30
+ target.listen(0, (err) => {
31
+ t.error(err)
32
+
33
+ instance.register(From, {
34
+ base: `http://localhost:${target.address().port}`
35
+ })
36
+
37
+ instance.listen(0, (err) => {
38
+ t.error(err)
39
+
40
+ get(`http://localhost:${instance.server.address().port}/hello?a=b`, (err, res, data) => {
41
+ t.error(err)
42
+ t.equal(res.headers['content-type'], 'text/plain')
43
+ t.equal(res.headers['x-my-header'], 'hello!')
44
+ t.equal(res.statusCode, 205)
45
+ t.equal(data.toString(), 'hello world')
46
+ })
47
+ })
48
+ })
@@ -0,0 +1,69 @@
1
+ 'use strict'
2
+
3
+ const { test } = require('tap')
4
+ const { buildURL } = require('../lib/utils')
5
+
6
+ test('should produce valid URL', (t) => {
7
+ t.plan(1)
8
+ const url = buildURL('/hi', 'http://localhost')
9
+ t.equal(url.href, 'http://localhost/hi')
10
+ })
11
+
12
+ test('should produce valid URL', (t) => {
13
+ t.plan(1)
14
+ const url = buildURL('http://localhost/hi', 'http://localhost')
15
+ t.equal(url.href, 'http://localhost/hi')
16
+ })
17
+
18
+ test('should return same source when base is not specified', (t) => {
19
+ t.plan(1)
20
+ const url = buildURL('http://localhost/hi')
21
+ t.equal(url.href, 'http://localhost/hi')
22
+ })
23
+
24
+ test('should handle lack of trailing slash in base', (t) => {
25
+ t.plan(3)
26
+ let url = buildURL('hi', 'http://localhost/hi')
27
+ t.equal(url.href, 'http://localhost/hi')
28
+
29
+ url = buildURL('hi/', 'http://localhost/hi')
30
+ t.equal(url.href, 'http://localhost/hi/')
31
+
32
+ url = buildURL('hi/more', 'http://localhost/hi')
33
+ t.equal(url.href, 'http://localhost/hi/more')
34
+ })
35
+
36
+ test('should handle default port in base', (t) => {
37
+ t.plan(2)
38
+ let url = buildURL('/hi', 'http://localhost:80/hi')
39
+ t.equal(url.href, 'http://localhost/hi')
40
+
41
+ url = buildURL('/hi', 'https://localhost:443/hi')
42
+ t.equal(url.href, 'https://localhost/hi')
43
+ })
44
+
45
+ const errorInputs = [
46
+ { source: '//10.0.0.10/hi', base: 'http://localhost' },
47
+ { source: 'http://10.0.0.10/hi', base: 'http://localhost' },
48
+ { source: 'https://10.0.0.10/hi', base: 'http://localhost' },
49
+ { source: 'blah://10.0.0.10/hi', base: 'http://localhost' },
50
+ { source: '//httpbin.org/hi', base: 'http://localhost' },
51
+ { source: 'urn:foo:bar', base: 'http://localhost' },
52
+ { source: 'http://localhost/private', base: 'http://localhost/exposed/' },
53
+ { source: 'http://localhost/exposed-extra', base: 'http://localhost/exposed' },
54
+ { source: '/private', base: 'http://localhost/exposed/' },
55
+ { source: '/exposed-extra', base: 'http://localhost/exposed' },
56
+ { source: '../private', base: 'http://localhost/exposed/' },
57
+ { source: 'exposed-extra', base: 'http://localhost/exposed' }
58
+ ]
59
+
60
+ test('should throw when trying to override base', (t) => {
61
+ t.plan(errorInputs.length)
62
+
63
+ errorInputs.forEach(({ source, base }) => {
64
+ t.test(source, (t) => {
65
+ t.plan(1)
66
+ t.throws(() => buildURL(source, base))
67
+ })
68
+ })
69
+ })
@@ -0,0 +1,50 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const Fastify = require('fastify')
5
+ const From = require('..')
6
+ const http = require('http')
7
+ const get = require('simple-get').concat
8
+
9
+ const instance = Fastify()
10
+
11
+ t.plan(11)
12
+ t.teardown(instance.close.bind(instance))
13
+
14
+ const target = http.createServer((req, res) => {
15
+ t.pass('request proxied')
16
+ t.equal(req.method, 'GET')
17
+ t.equal(req.url, '/hello')
18
+ t.equal(req.headers.connection, 'close')
19
+ res.statusCode = 205
20
+ res.setHeader('Content-Type', 'text/plain')
21
+ res.setHeader('x-my-header', 'hello!')
22
+ res.end('hello world')
23
+ })
24
+
25
+ instance.get('/', (request, reply) => {
26
+ reply.from('/hello')
27
+ })
28
+
29
+ t.teardown(target.close.bind(target))
30
+
31
+ target.listen(0, (err) => {
32
+ t.error(err)
33
+
34
+ instance.register(From, {
35
+ base: `http://localhost:${target.address().port}/hello`,
36
+ http: true
37
+ })
38
+
39
+ instance.listen(0, (err) => {
40
+ t.error(err)
41
+
42
+ get(`http://localhost:${instance.server.address().port}`, (err, res, data) => {
43
+ t.error(err)
44
+ t.equal(res.headers['content-type'], 'text/plain')
45
+ t.equal(res.headers['x-my-header'], 'hello!')
46
+ t.equal(res.statusCode, 205)
47
+ t.equal(data.toString(), 'hello world')
48
+ })
49
+ })
50
+ })
@@ -0,0 +1,77 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const Fastify = require('fastify')
5
+ const undici = require('undici')
6
+ const http = require('http')
7
+ const get = require('simple-get').concat
8
+ const From = require('..')
9
+
10
+ const target = http.createServer((req, res) => {
11
+ t.pass('request proxied')
12
+ t.equal(req.method, 'GET')
13
+ t.equal(req.url, '/')
14
+ t.equal(req.headers.connection, 'keep-alive')
15
+ res.statusCode = 205
16
+ res.setHeader('Content-Type', 'text/plain')
17
+ res.setHeader('x-my-header', 'hello!')
18
+ res.end('hello world')
19
+ })
20
+
21
+ t.test('use a custom instance of \'undici\'', async t => {
22
+ t.teardown(target.close.bind(target))
23
+
24
+ await new Promise((resolve, reject) => target.listen(0, err => err ? reject(err) : resolve()))
25
+
26
+ t.test('custom Pool', t => {
27
+ const instance = Fastify()
28
+ t.teardown(instance.close.bind(instance))
29
+ instance.register(From, {
30
+ base: `http://localhost:${target.address().port}`,
31
+ undici: new undici.Pool(`http://localhost:${target.address().port}`)
32
+ })
33
+
34
+ instance.get('/', (request, reply) => {
35
+ reply.from()
36
+ })
37
+
38
+ instance.listen(0, (err) => {
39
+ t.error(err)
40
+
41
+ get(`http://localhost:${instance.server.address().port}`, (err, res, data) => {
42
+ t.error(err)
43
+ t.equal(res.headers['content-type'], 'text/plain')
44
+ t.equal(res.headers['x-my-header'], 'hello!')
45
+ t.equal(res.statusCode, 205)
46
+ t.equal(data.toString(), 'hello world')
47
+ t.end()
48
+ })
49
+ })
50
+ })
51
+
52
+ t.test('custom Client', t => {
53
+ const instance = Fastify()
54
+ t.teardown(instance.close.bind(instance))
55
+ instance.register(From, {
56
+ base: `http://localhost:${target.address().port}`,
57
+ undici: new undici.Client(`http://localhost:${target.address().port}`)
58
+ })
59
+
60
+ instance.get('/', (request, reply) => {
61
+ reply.from()
62
+ })
63
+
64
+ instance.listen(0, (err) => {
65
+ t.error(err)
66
+
67
+ get(`http://localhost:${instance.server.address().port}`, (err, res, data) => {
68
+ t.error(err)
69
+ t.equal(res.headers['content-type'], 'text/plain')
70
+ t.equal(res.headers['x-my-header'], 'hello!')
71
+ t.equal(res.statusCode, 205)
72
+ t.equal(data.toString(), 'hello world')
73
+ t.end()
74
+ })
75
+ })
76
+ })
77
+ })
@@ -0,0 +1,90 @@
1
+ 'use strict'
2
+
3
+ const fs = require('fs')
4
+ const path = require('path')
5
+ const t = require('tap')
6
+ const Fastify = require('fastify')
7
+ const From = require('..')
8
+ const Multipart = require('fastify-multipart')
9
+ const http = require('http')
10
+ const get = require('simple-get').concat
11
+ const FormData = require('form-data')
12
+
13
+ const split = require('split2')
14
+ const logStream = split(JSON.parse)
15
+
16
+ const instance = Fastify({
17
+ logger: {
18
+ level: 'warn',
19
+ stream: logStream
20
+ }
21
+ })
22
+
23
+ instance.register(Multipart)
24
+ instance.register(From)
25
+
26
+ t.plan(12)
27
+
28
+ t.teardown(instance.close.bind(instance))
29
+
30
+ const filetPath = path.join(__dirname, 'fixtures', 'file.txt')
31
+ const fileContent = fs.readFileSync(filetPath, { encoding: 'utf-8' })
32
+
33
+ const target = http.createServer((req, res) => {
34
+ t.pass('request proxied')
35
+ t.equal(req.method, 'POST')
36
+ t.match(req.headers['content-type'], /^multipart\/form-data/)
37
+ let data = ''
38
+ req.setEncoding('utf8')
39
+ req.on('data', (d) => {
40
+ data += d
41
+ })
42
+ req.on('end', () => {
43
+ t.notMatch(data, 'Content-Disposition: form-data; name="key"')
44
+ t.notMatch(data, 'value')
45
+ t.notMatch(data, 'Content-Disposition: form-data; name="file"')
46
+ t.notMatch(data, fileContent)
47
+ res.setHeader('content-type', 'application/json')
48
+ res.statusCode = 200
49
+ res.end(JSON.stringify({ something: 'else' }))
50
+ })
51
+ })
52
+
53
+ instance.post('/', (request, reply) => {
54
+ reply.from(`http://localhost:${target.address().port}`)
55
+ })
56
+
57
+ t.teardown(target.close.bind(target))
58
+
59
+ instance.listen(0, (err) => {
60
+ t.error(err)
61
+
62
+ logStream.on('data', (log) => {
63
+ if (
64
+ log.level === 40 &&
65
+ log.msg.match(/fastify-reply-from might not behave as expected when used with fastify-multipart/)
66
+ ) {
67
+ t.pass('incompatibility warn message logged')
68
+ }
69
+ })
70
+
71
+ target.listen(0, (err) => {
72
+ t.error(err)
73
+
74
+ const form = new FormData()
75
+ form.append('key', 'value')
76
+ form.append('file', fs.createReadStream(filetPath, { encoding: 'utf-8' }))
77
+
78
+ get({
79
+ url: `http://localhost:${instance.server.address().port}`,
80
+ method: 'POST',
81
+ headers: {
82
+ ...form.getHeaders()
83
+ },
84
+ body: form
85
+ }, (err, res, data) => {
86
+ t.error(err)
87
+ t.same(JSON.parse(data), { something: 'else' })
88
+ })
89
+ })
90
+ })
@@ -0,0 +1,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDBzCCAe+gAwIBAgIJALbQMeb7k/WqMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNV
3
+ BAMMD3d3dy5mYXN0aWZ5Lm9yZzAeFw0xNzAyMDcyMDE5NDJaFw0yNzAyMDUyMDE5
4
+ NDJaMBoxGDAWBgNVBAMMD3d3dy5mYXN0aWZ5Lm9yZzCCASIwDQYJKoZIhvcNAQEB
5
+ BQADggEPADCCAQoCggEBAKtfXzDMmU+n3A7oVVOiqp6Z5cgu1t+qgj7TadwXONvO
6
+ RZvuOcE8BZpM9tQEDE5XEIdcszDx0tWKHHSobgZAxDaEuK1PMhh/RTNvw1KzYJFm
7
+ 2G38mqgm11JUni87xmIFqpgJfeCApHnWUv+3/npuQniOoVSL13jdXEifeFM8onQn
8
+ R73TVDyvMOjljTulMo0n9V8pYhVSzPnm2uxTu03p5+HosQE2bU0QKj7k8/8dwRVX
9
+ EqnTtbLoW+Wf7V2W3cr/UnfPH8JSaBWTqct0pgXqYIqOSTiWQkO7pE69mGPHrRlm
10
+ 7+whp4WRriTacB3Ul+Cbx28wHU+D83ver4A8LKGVDSECAwEAAaNQME4wHQYDVR0O
11
+ BBYEFHVzTr/tNziIUrR75UHXXA84yqmgMB8GA1UdIwQYMBaAFHVzTr/tNziIUrR7
12
+ 5UHXXA84yqmgMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKVSdGeF
13
+ vYcZOi0TG2WX7O3tSmu4G4nGxTldFiEVF89G0AU+HhNy9iwKXQLjDB7zMe/ZKbtJ
14
+ cQgc6s8eZWxBk/OoPD1WNFGstx2EO2kRkSUBKhwnOct7CIS5X+NPXyHx2Yi03JHX
15
+ unMA4WaHyo0dK4vAuali4OYdQqajNwL74avkRIxXFnZQeHzaq6tc6gX+ryB4dDSr
16
+ tYn46Lo14D5jH6PtZ8DlGK+jIzM4IE7TEp2iv0CgaTU4ryt/SHPnLxfwZUpl7gSO
17
+ EqkMAy3TlRMpv0oXM2Vh/CsyJzq2P/nY/O3bolsashSPWo9WsQTH4giYVA51ZVDK
18
+ lGksQD+oWpfa3X0=
19
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEpQIBAAKCAQEAq19fMMyZT6fcDuhVU6KqnpnlyC7W36qCPtNp3Bc4285Fm+45
3
+ wTwFmkz21AQMTlcQh1yzMPHS1YocdKhuBkDENoS4rU8yGH9FM2/DUrNgkWbYbfya
4
+ qCbXUlSeLzvGYgWqmAl94ICkedZS/7f+em5CeI6hVIvXeN1cSJ94UzyidCdHvdNU
5
+ PK8w6OWNO6UyjSf1XyliFVLM+eba7FO7Tenn4eixATZtTRAqPuTz/x3BFVcSqdO1
6
+ suhb5Z/tXZbdyv9Sd88fwlJoFZOpy3SmBepgio5JOJZCQ7ukTr2YY8etGWbv7CGn
7
+ hZGuJNpwHdSX4JvHbzAdT4Pze96vgDwsoZUNIQIDAQABAoIBAG278ys/R8he1yVg
8
+ lgqo9ZH7P8zwWTz9ZMsv+vAomor9SUtwvuDCO2AzejYGpY6gZ4AV1tQ3dOaxukjk
9
+ 9Rbh8AJs+AhZ1t0i2b/3B95z6BkS/vFmt+2GeYhJkMT0BLMNp9AU+9p+5VLy71C5
10
+ k6T3525k/l8x8HZ/YDFMk/LQt8GhvM6A3J3BNElKraiDVO6ZIWgQQ5wiefJkApo1
11
+ BsptHNTx83FbnkEbAahmOR8PfKcRdKY/mZDM2WrlfoU2uwVzPV0/KdYucpsfg2et
12
+ jb5bdJzcvZDuDF4GsPi1asCSC1c403R0XGuPFW9TiBuOPxbfhYK2o60yTggX6H2X
13
+ 39WBc/ECgYEA3KNGgXEWzDSLpGciUisP+MzulOdQPawBTUHNykpQklEppnZbNWCX
14
+ 07dv6uasnp0pFHG4WlhZJ4+IQBpZH6xAVy9y68PvN7IDYdgMiEiYPSyqQu0rvJGa
15
+ 2ZR79SHDokZ8K5oofocC839RzleNRqWqxIwhHt29sxVs73kvml6OQm0CgYEAxtbA
16
+ zbQwf6DXtFwutSgfOLgdXQK72beBdyeTcpUGbkonl5xHSbtz0CFmRpKiPnXfgg4W
17
+ GXlTrqlYF/o048B7dU9+jCKY5DXx1Yzg/EFisEIClad3WXMhNOz1vBYVH6xU3Zq1
18
+ YuYr5dcqiCWDv89e6Y6WJOhwIDZi6RqikD2EJQUCgYEAnWSAJFCnIa8OOo4z5oe/
19
+ kg2m2GQWUphEKXeatQbEaUwquQvPTsmEJUzDMr+xPkkAiAwDpbdGijkSyh/Bmh2H
20
+ nGpFwbf5CzMaxI6ZihK3P1SAdNO5koAQBcytjJW0eCtt4rDK2E+5pDgcBGVia5Y8
21
+ to78BYfLDlhnaIF7mtR/CRUCgYEAvGCuzvOcUv4F/eirk5NMaQb9QqYZZD2XWVTU
22
+ O2T2b7yvX9J+M1t1cESESe4X6cbwlp1T0JSCdGIZhLXWL8Om80/52zfX07VLxP6w
23
+ FCy6G7SeEDxVNRh+6E5qzOO65YP17vDoUacxBZJgyBWKiUkkaW9dzd+sgsgj0yYZ
24
+ xz+QlyUCgYEAxdNWQnz0pR5Rt2dbIedPs7wmiZ7eAe0VjCdhMa52IyJpejdeB6Bn
25
+ Es+3lkHr0Xzty8XlQZcpbswhM8UZRgPVoBvvwQdQbv5yV+LdUu69pLM7InsdZy8u
26
+ opPY/+q9lRdJt4Pbep3pOWYeLP7k5l4vei2vOEMHRjHnoqM5etSb6RU=
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ file content
@@ -0,0 +1,45 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const Fastify = require('fastify')
5
+ const From = require('..')
6
+ const http = require('http')
7
+ const get = require('simple-get').concat
8
+
9
+ const instance = Fastify()
10
+ instance.register(From)
11
+
12
+ t.plan(10)
13
+ t.teardown(instance.close.bind(instance))
14
+
15
+ const target = http.createServer((req, res) => {
16
+ t.pass('request proxied')
17
+ t.equal(req.method, 'GET')
18
+ t.equal(req.url, '/hello')
19
+ res.statusCode = 205
20
+ res.setHeader('Content-Type', 'text/plain')
21
+ res.setHeader('x-my-header', 'hello!')
22
+ res.end('hello world')
23
+ })
24
+
25
+ instance.get('/', (request, reply) => {
26
+ reply.from(`http://localhost:${target.address().port}/hello`)
27
+ })
28
+
29
+ t.teardown(target.close.bind(target))
30
+
31
+ instance.listen(0, (err) => {
32
+ t.error(err)
33
+
34
+ target.listen(0, (err) => {
35
+ t.error(err)
36
+
37
+ get(`http://localhost:${instance.server.address().port}`, (err, res, data) => {
38
+ t.error(err)
39
+ t.equal(res.headers['content-type'], 'text/plain')
40
+ t.equal(res.headers['x-my-header'], 'hello!')
41
+ t.equal(res.statusCode, 205)
42
+ t.equal(data.toString(), 'hello world')
43
+ })
44
+ })
45
+ })
@@ -0,0 +1,55 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const Fastify = require('fastify')
5
+ const From = require('..')
6
+ const https = require('https')
7
+ const get = require('simple-get').concat
8
+ const fs = require('fs')
9
+ const path = require('path')
10
+ const certs = {
11
+ key: fs.readFileSync(path.join(__dirname, 'fixtures', 'fastify.key')),
12
+ cert: fs.readFileSync(path.join(__dirname, 'fixtures', 'fastify.cert'))
13
+ }
14
+
15
+ const instance = Fastify({
16
+ https: certs
17
+ })
18
+ instance.register(From)
19
+
20
+ t.plan(9)
21
+ t.teardown(instance.close.bind(instance))
22
+
23
+ const target = https.createServer(certs, (req, res) => {
24
+ t.pass('request proxied')
25
+ t.equal(req.method, 'GET')
26
+ res.statusCode = 205
27
+ res.setHeader('Content-Type', 'text/plain')
28
+ res.setHeader('x-my-header', 'hello!')
29
+ res.end('hello world')
30
+ })
31
+
32
+ instance.get('/', (request, reply) => {
33
+ reply.from(`https://localhost:${target.address().port}`)
34
+ })
35
+
36
+ t.teardown(target.close.bind(target))
37
+
38
+ instance.listen(0, (err) => {
39
+ t.error(err)
40
+
41
+ target.listen(0, (err) => {
42
+ t.error(err)
43
+
44
+ get({
45
+ url: `https://localhost:${instance.server.address().port}`,
46
+ rejectUnauthorized: false
47
+ }, (err, res, data) => {
48
+ t.error(err)
49
+ t.equal(res.headers['content-type'], 'text/plain')
50
+ t.equal(res.headers['x-my-header'], 'hello!')
51
+ t.equal(res.statusCode, 205)
52
+ t.equal(data.toString(), 'hello world')
53
+ })
54
+ })
55
+ })
@@ -0,0 +1,59 @@
1
+ 'use strict'
2
+
3
+ const t = require('tap')
4
+ const Fastify = require('fastify')
5
+ const From = require('..')
6
+ const http = require('http')
7
+ const get = require('simple-get')
8
+
9
+ const instance = Fastify()
10
+ instance.register(From)
11
+
12
+ t.plan(9)
13
+ t.teardown(instance.close.bind(instance))
14
+
15
+ const target = http.createServer((req, res) => {
16
+ t.pass('request proxied')
17
+ t.equal(req.method, 'POST')
18
+ t.equal(req.headers['content-type'].startsWith('application/json'), true)
19
+ let data = ''
20
+ req.setEncoding('utf8')
21
+ req.on('data', (d) => {
22
+ data += d
23
+ })
24
+ req.on('end', () => {
25
+ t.same(JSON.parse(data), { hello: 'world' })
26
+ res.statusCode = 200
27
+ res.setHeader('content-type', 'application/json')
28
+ res.end(JSON.stringify({ something: 'else' }))
29
+ })
30
+ })
31
+
32
+ instance.post('/', (request, reply) => {
33
+ reply.from(`http://localhost:${target.address().port}`)
34
+ })
35
+
36
+ t.teardown(target.close.bind(target))
37
+
38
+ instance.listen(0, (err) => {
39
+ t.error(err)
40
+
41
+ target.listen(0, (err) => {
42
+ t.error(err)
43
+
44
+ get.concat({
45
+ url: `http://localhost:${instance.server.address().port}`,
46
+ method: 'POST',
47
+ body: JSON.stringify({
48
+ hello: 'world'
49
+ }),
50
+ headers: {
51
+ 'content-type': 'application/json;charset=utf-8'
52
+ }
53
+ }, (err, res, data) => {
54
+ t.error(err)
55
+ t.equal(res.headers['content-type'], 'application/json')
56
+ t.same(JSON.parse(data.toString()), { something: 'else' })
57
+ })
58
+ })
59
+ })