@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.
- package/.github/dependabot.yml +13 -0
- package/.github/stale.yml +21 -0
- package/.github/workflows/ci.yml +60 -0
- package/.taprc +5 -0
- package/LICENSE +21 -0
- package/README.md +335 -0
- package/example.js +36 -0
- package/index.d.ts +99 -0
- package/index.js +262 -0
- package/lib/request.js +288 -0
- package/lib/utils.js +81 -0
- package/package.json +70 -0
- package/test/async-route-handler.js +50 -0
- package/test/base-get.js +48 -0
- package/test/base-path.js +38 -0
- package/test/base-querystring.js +48 -0
- package/test/build-url.js +69 -0
- package/test/core-with-path-in-base.js +50 -0
- package/test/custom-undici-instance.js +77 -0
- package/test/fastify-multipart-incompatibility.js +90 -0
- package/test/fixtures/fastify.cert +19 -0
- package/test/fixtures/fastify.key +27 -0
- package/test/fixtures/file.txt +1 -0
- package/test/full-get.js +45 -0
- package/test/full-https-get.js +55 -0
- package/test/full-post-extended-content-type.js +59 -0
- package/test/full-post-http2.js +49 -0
- package/test/full-post-stream-core.js +66 -0
- package/test/full-post-stream.js +64 -0
- package/test/full-post.js +56 -0
- package/test/full-querystring-rewrite-option-complex.js +48 -0
- package/test/full-querystring-rewrite-option-function.js +51 -0
- package/test/full-querystring-rewrite-option.js +48 -0
- package/test/full-querystring-rewrite-string.js +46 -0
- package/test/full-querystring-rewrite.js +46 -0
- package/test/full-querystring.js +46 -0
- package/test/full-rewrite-body-content-type.js +59 -0
- package/test/full-rewrite-body-http.js +63 -0
- package/test/full-rewrite-body-to-empty-string.js +61 -0
- package/test/full-rewrite-body-to-null.js +61 -0
- package/test/full-rewrite-body.js +61 -0
- package/test/get-upstream-http.js +70 -0
- package/test/get-upstream-undici.js +45 -0
- package/test/get-with-body.js +55 -0
- package/test/head-with-body.js +57 -0
- package/test/host-header.js +67 -0
- package/test/http-agents.js +55 -0
- package/test/http-http2.js +50 -0
- package/test/http-invalid-target.js +35 -0
- package/test/http-retry.js +109 -0
- package/test/http-timeout.js +56 -0
- package/test/http2-http2.js +57 -0
- package/test/http2-https.js +80 -0
- package/test/http2-invalid-target.js +36 -0
- package/test/http2-target-crash.js +53 -0
- package/test/http2-target-multi-crash.js +60 -0
- package/test/http2-timeout.js +92 -0
- package/test/https-agents.js +67 -0
- package/test/index.test-d.ts +136 -0
- package/test/modifyCoreObjects-false.js +48 -0
- package/test/no-body-opts-with-get.js +49 -0
- package/test/no-body-opts-with-head.js +51 -0
- package/test/no-stream-body-option.js +58 -0
- package/test/on-error.js +62 -0
- package/test/onResponse.js +48 -0
- package/test/padded-body.js +64 -0
- package/test/post-formbody.js +59 -0
- package/test/post-plain-text.js +56 -0
- package/test/post-with-custom-encoded-contenttype.js +65 -0
- package/test/retry-on-503.js +101 -0
- package/test/rewrite-headers.js +52 -0
- package/test/rewrite-request-headers.js +47 -0
- package/test/transform-body.js +61 -0
- package/test/undici-agent.js +77 -0
- package/test/undici-body.js +70 -0
- package/test/undici-options.js +73 -0
- package/test/undici-retry.js +109 -0
- package/test/undici-timeout-body-partial.js +60 -0
- package/test/undici-timeout-body.js +63 -0
- package/test/undici-timeout.js +61 -0
- package/test/undici-with-path-in-base.js +50 -0
- package/test/undici.js +50 -0
- package/test/unexpected-error.js +46 -0
- package/test/unix-http-undici-from.js +51 -0
- package/test/unix-http-undici.js +62 -0
- package/test/unix-http.js +65 -0
- package/test/unix-https-undici.js +71 -0
- 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
|
+
})
|
package/test/base-get.js
ADDED
|
@@ -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
|
package/test/full-get.js
ADDED
|
@@ -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
|
+
})
|