@fastify/reply-from 12.1.0 → 12.3.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/.claude/settings.local.json +9 -0
- package/.github/workflows/ci.yml +3 -0
- package/LICENSE +4 -1
- package/README.md +20 -0
- package/index.js +10 -0
- package/lib/request.js +13 -3
- package/lib/utils.js +1 -0
- package/package.json +6 -8
- package/test/async-route-handler.test.js +29 -32
- package/test/balanced-pool.test.js +48 -0
- package/test/base-get.test.js +27 -30
- package/test/base-path.test.js +27 -24
- package/test/base-querystring.test.js +27 -30
- package/test/build-url.test.js +17 -15
- package/test/core-with-path-in-base.test.js +30 -33
- package/test/custom-undici-instance.test.js +28 -36
- package/test/disable-request-logging.test.js +38 -52
- package/test/fastify-multipart-incompatibility.test.js +43 -49
- package/test/fix-GHSA-v2v2-hph8-q5xp.test.js +3 -2
- package/test/full-delete-http2.test.js +12 -11
- package/test/full-get-test.test.js +27 -30
- package/test/full-https-get.test.js +30 -30
- package/test/full-post-extended-content-type.test.js +40 -44
- package/test/full-post-http2.test.js +18 -13
- package/test/full-post-stream-core.test.js +39 -43
- package/test/full-post-stream.test.js +39 -43
- package/test/full-post.test.js +36 -38
- package/test/full-querystring-rewrite-option-complex.test.js +27 -31
- package/test/full-querystring-rewrite-option-function-request.test.js +30 -36
- package/test/full-querystring-rewrite-option-function.test.js +30 -33
- package/test/full-querystring-rewrite-option.test.js +28 -31
- package/test/full-querystring-rewrite-string.test.js +27 -30
- package/test/full-querystring-rewrite.test.js +27 -30
- package/test/full-querystring.test.js +27 -30
- package/test/full-rewrite-body-content-type.test.js +37 -41
- package/test/full-rewrite-body-http.test.js +39 -43
- package/test/full-rewrite-body-to-empty-string.test.js +37 -41
- package/test/full-rewrite-body-to-null.test.js +37 -41
- package/test/full-rewrite-body.test.js +39 -43
- package/test/get-upstream-cache.test.js +12 -11
- package/test/get-upstream-http.test.js +35 -41
- package/test/get-upstream-type.test.js +24 -27
- package/test/get-upstream-undici.test.js +23 -26
- package/test/host-header.test.js +22 -18
- package/test/http-agents.test.js +27 -30
- package/test/http-global-agent.test.js +20 -33
- package/test/http-http2.test.js +13 -18
- package/test/http-invalid-target.test.js +13 -17
- package/test/http-retry.test.js +22 -29
- package/test/http-timeout.test.js +49 -42
- package/test/http2-canceled-streams-cleanup.test.js +117 -0
- package/test/http2-goaway.test.js +126 -0
- package/test/http2-http2.test.js +8 -8
- package/test/http2-https.test.js +29 -27
- package/test/http2-invalid-base.test.js +2 -2
- package/test/http2-invalid-target.test.js +13 -17
- package/test/http2-target-crash.test.js +16 -20
- package/test/http2-target-multi-crash.test.js +22 -27
- package/test/http2-timeout-disabled.test.js +20 -15
- package/test/http2-timeout.test.js +58 -65
- package/test/http2-unix-socket.test.js +2 -2
- package/test/https-agents.test.js +31 -30
- package/test/https-global-agent.test.js +22 -31
- package/test/method.test.js +37 -42
- package/test/modifyCoreObjects-false.test.js +27 -30
- package/test/no-body-opts-with-get.test.js +25 -31
- package/test/no-body-opts-with-head.test.js +28 -32
- package/test/no-stream-body-option.test.js +34 -36
- package/test/on-error.test.js +21 -23
- package/test/on-invalid-upstream-response.test.js +30 -37
- package/test/onResponse.test.js +25 -32
- package/test/padded-body.test.js +38 -43
- package/test/post-formbody.test.js +35 -40
- package/test/post-plain-text.test.js +35 -39
- package/test/post-with-custom-encoded-contenttype.test.js +37 -39
- package/test/post-with-octet-stream.test.js +18 -88
- package/test/retry-on-503.test.js +27 -26
- package/test/retry-with-a-custom-handler.test.js +33 -40
- package/test/rewrite-headers-type.test.js +24 -29
- package/test/rewrite-headers.test.js +31 -36
- package/test/rewrite-request-headers-type.test.js +25 -28
- package/test/rewrite-request-headers.test.js +26 -30
- package/test/transform-body.test.js +37 -43
- package/test/undici-agent.test.js +27 -31
- package/test/undici-body.test.js +37 -42
- package/test/undici-chaining.test.js +35 -42
- package/test/undici-connect-timeout.test.js +13 -13
- package/test/undici-custom-dispatcher.test.js +11 -11
- package/test/undici-global-agent.test.js +14 -33
- package/test/undici-no-destroy.test.js +2 -2
- package/test/undici-options.test.js +21 -24
- package/test/undici-proxy-agent.test.js +4 -3
- package/test/undici-retry.test.js +24 -31
- package/test/undici-timeout-body-partial.test.js +14 -16
- package/test/undici-timeout-body.test.js +17 -19
- package/test/undici-timeout.test.js +41 -37
- package/test/undici-with-path-in-base.test.js +28 -31
- package/test/undici.test.js +28 -31
- package/test/unexpected-error.test.js +13 -18
- package/test/unix-http-undici-from.test.js +22 -31
- package/test/unix-http-undici.test.js +32 -40
- package/test/unix-http.test.js +31 -39
- package/test/unix-https-undici.test.js +30 -35
- package/test/unix-https.test.js +35 -40
- package/types/index.d.ts +9 -2
- package/types/index.test-d.ts +3 -4
- package/test/get-with-body.test.js +0 -55
- package/test/head-with-body.test.js +0 -57
|
@@ -1,53 +1,50 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const t = require('
|
|
3
|
+
const t = require('node:test')
|
|
4
4
|
const Fastify = require('fastify')
|
|
5
|
+
const { request, Agent } = require('undici')
|
|
5
6
|
const From = require('..')
|
|
6
7
|
const http = require('node:http')
|
|
7
|
-
const get = require('simple-get').concat
|
|
8
8
|
|
|
9
9
|
const instance = Fastify()
|
|
10
10
|
|
|
11
|
-
t.
|
|
12
|
-
t.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
t.test('core with path in base', async (t) => {
|
|
12
|
+
t.plan(8)
|
|
13
|
+
t.after(() => instance.close())
|
|
14
|
+
|
|
15
|
+
const target = http.createServer((req, res) => {
|
|
16
|
+
t.assert.ok('request proxied')
|
|
17
|
+
t.assert.strictEqual(req.method, 'GET')
|
|
18
|
+
t.assert.strictEqual(req.url, '/hello')
|
|
19
|
+
t.assert.strictEqual(req.headers.connection, 'close')
|
|
20
|
+
res.statusCode = 205
|
|
21
|
+
res.setHeader('Content-Type', 'text/plain')
|
|
22
|
+
res.setHeader('x-my-header', 'hello!')
|
|
23
|
+
res.end('hello world')
|
|
24
|
+
})
|
|
24
25
|
|
|
25
|
-
instance.get('/', (_request, reply) => {
|
|
26
|
-
|
|
27
|
-
})
|
|
26
|
+
instance.get('/', (_request, reply) => {
|
|
27
|
+
reply.from('/hello')
|
|
28
|
+
})
|
|
28
29
|
|
|
29
|
-
t.
|
|
30
|
+
t.after(() => target.close())
|
|
30
31
|
|
|
31
|
-
target.listen({ port: 0 },
|
|
32
|
-
t.error(err)
|
|
32
|
+
await new Promise(resolve => target.listen({ port: 0 }, resolve))
|
|
33
33
|
|
|
34
34
|
instance.register(From, {
|
|
35
35
|
base: `http://localhost:${target.address().port}/hello`,
|
|
36
36
|
http: true
|
|
37
37
|
})
|
|
38
38
|
|
|
39
|
-
instance.listen({ port: 0 },
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
agent: false
|
|
45
|
-
}, (err, res, data) => {
|
|
46
|
-
t.error(err)
|
|
47
|
-
t.equal(res.headers['content-type'], 'text/plain')
|
|
48
|
-
t.equal(res.headers['x-my-header'], 'hello!')
|
|
49
|
-
t.equal(res.statusCode, 205)
|
|
50
|
-
t.equal(data.toString(), 'hello world')
|
|
39
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
40
|
+
|
|
41
|
+
const result = await request(`http://localhost:${instance.server.address().port}`, {
|
|
42
|
+
dispatcher: new Agent({
|
|
43
|
+
pipelining: 0
|
|
51
44
|
})
|
|
52
45
|
})
|
|
46
|
+
t.assert.strictEqual(result.headers['content-type'], 'text/plain')
|
|
47
|
+
t.assert.strictEqual(result.headers['x-my-header'], 'hello!')
|
|
48
|
+
t.assert.strictEqual(result.statusCode, 205)
|
|
49
|
+
t.assert.strictEqual(await result.body.text(), 'hello world')
|
|
53
50
|
})
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const t = require('
|
|
3
|
+
const t = require('node:test')
|
|
4
|
+
const assert = require('node:assert')
|
|
4
5
|
const Fastify = require('fastify')
|
|
5
|
-
const
|
|
6
|
+
const { Pool, request, Client } = require('undici')
|
|
6
7
|
const http = require('node:http')
|
|
7
|
-
const get = require('simple-get').concat
|
|
8
8
|
const From = require('..')
|
|
9
9
|
|
|
10
10
|
const target = http.createServer((req, res) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
assert.ok('request proxied')
|
|
12
|
+
assert.strictEqual(req.method, 'GET')
|
|
13
|
+
assert.strictEqual(req.url, '/')
|
|
14
|
+
assert.strictEqual(req.headers.connection, 'keep-alive')
|
|
15
15
|
res.statusCode = 205
|
|
16
16
|
res.setHeader('Content-Type', 'text/plain')
|
|
17
17
|
res.setHeader('x-my-header', 'hello!')
|
|
@@ -19,59 +19,51 @@ const target = http.createServer((req, res) => {
|
|
|
19
19
|
})
|
|
20
20
|
|
|
21
21
|
t.test('use a custom instance of \'undici\'', async t => {
|
|
22
|
-
t.
|
|
22
|
+
t.after(() => target.close())
|
|
23
23
|
|
|
24
24
|
await new Promise((resolve, reject) => target.listen({ port: 0 }, err => err ? reject(err) : resolve()))
|
|
25
25
|
|
|
26
|
-
t.test('custom Pool', t => {
|
|
26
|
+
await t.test('custom Pool', async t => {
|
|
27
27
|
const instance = Fastify()
|
|
28
|
-
t.
|
|
28
|
+
t.after(() => instance.close())
|
|
29
29
|
instance.register(From, {
|
|
30
30
|
base: `http://localhost:${target.address().port}`,
|
|
31
|
-
undici: new
|
|
31
|
+
undici: new Pool(`http://localhost:${target.address().port}`)
|
|
32
32
|
})
|
|
33
33
|
|
|
34
34
|
instance.get('/', (_request, reply) => {
|
|
35
35
|
reply.from()
|
|
36
36
|
})
|
|
37
37
|
|
|
38
|
-
instance.listen({ port: 0 },
|
|
39
|
-
t.error(err)
|
|
38
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
t.end()
|
|
48
|
-
})
|
|
49
|
-
})
|
|
40
|
+
const result = await request(`http://localhost:${instance.server.address().port}`)
|
|
41
|
+
|
|
42
|
+
t.assert.strictEqual(result.headers['content-type'], 'text/plain')
|
|
43
|
+
t.assert.strictEqual(result.headers['x-my-header'], 'hello!')
|
|
44
|
+
t.assert.strictEqual(result.statusCode, 205)
|
|
45
|
+
t.assert.strictEqual(await result.body.text(), 'hello world')
|
|
50
46
|
})
|
|
51
47
|
|
|
52
|
-
t.test('custom Client', t => {
|
|
48
|
+
await t.test('custom Client', async t => {
|
|
53
49
|
const instance = Fastify()
|
|
54
|
-
t.
|
|
50
|
+
t.after(() => instance.close())
|
|
55
51
|
instance.register(From, {
|
|
56
52
|
base: `http://localhost:${target.address().port}`,
|
|
57
|
-
undici: new
|
|
53
|
+
undici: new Client(`http://localhost:${target.address().port}`)
|
|
58
54
|
})
|
|
59
55
|
|
|
60
56
|
instance.get('/', (_request, reply) => {
|
|
61
57
|
reply.from()
|
|
62
58
|
})
|
|
63
59
|
|
|
64
|
-
instance.listen({ port: 0 },
|
|
65
|
-
t.error(err)
|
|
60
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
66
61
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
t.end()
|
|
74
|
-
})
|
|
75
|
-
})
|
|
62
|
+
const result = await request(`http://localhost:${instance.server.address().port}`)
|
|
63
|
+
|
|
64
|
+
t.assert.strictEqual(result.headers['content-type'], 'text/plain')
|
|
65
|
+
t.assert.strictEqual(result.headers['x-my-header'], 'hello!')
|
|
66
|
+
t.assert.strictEqual(result.statusCode, 205)
|
|
67
|
+
t.assert.strictEqual(await result.body.text(), 'hello world')
|
|
76
68
|
})
|
|
77
69
|
})
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const t = require('
|
|
3
|
+
const t = require('node:test')
|
|
4
|
+
const assert = require('node:assert')
|
|
4
5
|
const Fastify = require('fastify')
|
|
6
|
+
const { request } = require('undici')
|
|
5
7
|
const From = require('..')
|
|
6
8
|
const http = require('node:http')
|
|
7
|
-
const get = require('simple-get').concat
|
|
8
9
|
const split = require('split2')
|
|
9
10
|
|
|
10
11
|
const target = http.createServer((req, res) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
assert.ok('request proxied')
|
|
13
|
+
assert.strictEqual(req.method, 'GET')
|
|
14
|
+
assert.strictEqual(req.url, '/')
|
|
15
|
+
assert.strictEqual(req.headers.connection, 'keep-alive')
|
|
15
16
|
res.statusCode = 205
|
|
16
17
|
res.setHeader('Content-Type', 'text/plain')
|
|
17
18
|
res.setHeader('x-my-header', 'hello!')
|
|
@@ -20,11 +21,11 @@ const target = http.createServer((req, res) => {
|
|
|
20
21
|
|
|
21
22
|
t.test('use a custom instance of \'undici\'', async t => {
|
|
22
23
|
t.plan(3)
|
|
23
|
-
t.
|
|
24
|
+
t.after(() => target.close())
|
|
24
25
|
|
|
25
26
|
await new Promise((resolve, reject) => target.listen({ port: 0 }, err => err ? reject(err) : resolve()))
|
|
26
27
|
|
|
27
|
-
t.test('disableRequestLogging is set to true', t => {
|
|
28
|
+
await t.test('disableRequestLogging is set to true', async t => {
|
|
28
29
|
const logStream = split(JSON.parse)
|
|
29
30
|
const instance = Fastify({
|
|
30
31
|
logger: {
|
|
@@ -32,7 +33,7 @@ t.test('use a custom instance of \'undici\'', async t => {
|
|
|
32
33
|
stream: logStream
|
|
33
34
|
}
|
|
34
35
|
})
|
|
35
|
-
t.
|
|
36
|
+
t.after(() => instance.close())
|
|
36
37
|
instance.register(From, {
|
|
37
38
|
base: `http://localhost:${target.address().port}`,
|
|
38
39
|
disableRequestLogging: true
|
|
@@ -50,25 +51,20 @@ t.test('use a custom instance of \'undici\'', async t => {
|
|
|
50
51
|
!log.msg.match('fetching from remote server')
|
|
51
52
|
)
|
|
52
53
|
) {
|
|
53
|
-
t.
|
|
54
|
+
t.assert.ok('request log message does not logged')
|
|
54
55
|
}
|
|
55
56
|
})
|
|
56
57
|
|
|
57
|
-
instance.listen({ port: 0 },
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
t.equal(res.statusCode, 205)
|
|
65
|
-
t.equal(data.toString(), 'hello world')
|
|
66
|
-
t.end()
|
|
67
|
-
})
|
|
68
|
-
})
|
|
58
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
59
|
+
|
|
60
|
+
const result = await request(`http://localhost:${instance.server.address().port}`)
|
|
61
|
+
t.assert.strictEqual(result.headers['content-type'], 'text/plain')
|
|
62
|
+
t.assert.strictEqual(result.headers['x-my-header'], 'hello!')
|
|
63
|
+
t.assert.strictEqual(result.statusCode, 205)
|
|
64
|
+
t.assert.strictEqual(await result.body.text(), 'hello world')
|
|
69
65
|
})
|
|
70
66
|
|
|
71
|
-
t.test('disableRequestLogging is set to false', t => {
|
|
67
|
+
await t.test('disableRequestLogging is set to false', async t => {
|
|
72
68
|
const logStream = split(JSON.parse)
|
|
73
69
|
const instance = Fastify({
|
|
74
70
|
logger: {
|
|
@@ -76,7 +72,7 @@ t.test('use a custom instance of \'undici\'', async t => {
|
|
|
76
72
|
stream: logStream
|
|
77
73
|
}
|
|
78
74
|
})
|
|
79
|
-
t.
|
|
75
|
+
t.after(() => instance.close())
|
|
80
76
|
instance.register(From, {
|
|
81
77
|
base: `http://localhost:${target.address().port}`,
|
|
82
78
|
disableRequestLogging: false
|
|
@@ -94,25 +90,20 @@ t.test('use a custom instance of \'undici\'', async t => {
|
|
|
94
90
|
log.msg.match('fetching from remote server')
|
|
95
91
|
)
|
|
96
92
|
) {
|
|
97
|
-
t.
|
|
93
|
+
t.assert.ok('request log message does not logged')
|
|
98
94
|
}
|
|
99
95
|
})
|
|
100
96
|
|
|
101
|
-
instance.listen({ port: 0 },
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
t.equal(res.statusCode, 205)
|
|
109
|
-
t.equal(data.toString(), 'hello world')
|
|
110
|
-
t.end()
|
|
111
|
-
})
|
|
112
|
-
})
|
|
97
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
98
|
+
|
|
99
|
+
const result = await request(`http://localhost:${instance.server.address().port}`)
|
|
100
|
+
t.assert.strictEqual(result.headers['content-type'], 'text/plain')
|
|
101
|
+
t.assert.strictEqual(result.headers['x-my-header'], 'hello!')
|
|
102
|
+
t.assert.strictEqual(result.statusCode, 205)
|
|
103
|
+
t.assert.strictEqual(await result.body.text(), 'hello world')
|
|
113
104
|
})
|
|
114
105
|
|
|
115
|
-
t.test('disableRequestLogging is not defined', t => {
|
|
106
|
+
await t.test('disableRequestLogging is not defined', async t => {
|
|
116
107
|
const logStream = split(JSON.parse)
|
|
117
108
|
const instance = Fastify({
|
|
118
109
|
logger: {
|
|
@@ -120,7 +111,7 @@ t.test('use a custom instance of \'undici\'', async t => {
|
|
|
120
111
|
stream: logStream
|
|
121
112
|
}
|
|
122
113
|
})
|
|
123
|
-
t.
|
|
114
|
+
t.after(() => instance.close())
|
|
124
115
|
instance.register(From, {
|
|
125
116
|
base: `http://localhost:${target.address().port}`
|
|
126
117
|
})
|
|
@@ -137,21 +128,16 @@ t.test('use a custom instance of \'undici\'', async t => {
|
|
|
137
128
|
log.msg.match('fetching from remote server')
|
|
138
129
|
)
|
|
139
130
|
) {
|
|
140
|
-
t.
|
|
131
|
+
t.assert.ok('request log message does not logged')
|
|
141
132
|
}
|
|
142
133
|
})
|
|
143
134
|
|
|
144
|
-
instance.listen({ port: 0 },
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
t.equal(res.statusCode, 205)
|
|
152
|
-
t.equal(data.toString(), 'hello world')
|
|
153
|
-
t.end()
|
|
154
|
-
})
|
|
155
|
-
})
|
|
135
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
136
|
+
|
|
137
|
+
const result = await request(`http://localhost:${instance.server.address().port}`)
|
|
138
|
+
t.assert.strictEqual(result.headers['content-type'], 'text/plain')
|
|
139
|
+
t.assert.strictEqual(result.headers['x-my-header'], 'hello!')
|
|
140
|
+
t.assert.strictEqual(result.statusCode, 205)
|
|
141
|
+
t.assert.strictEqual(await result.body.text(), 'hello world')
|
|
156
142
|
})
|
|
157
143
|
})
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('node:fs')
|
|
4
4
|
const path = require('node:path')
|
|
5
|
-
const t = require('
|
|
5
|
+
const t = require('node:test')
|
|
6
6
|
const Fastify = require('fastify')
|
|
7
|
+
const { request } = require('undici')
|
|
7
8
|
const From = require('..')
|
|
8
9
|
const Multipart = require('@fastify/multipart')
|
|
9
10
|
const http = require('node:http')
|
|
10
|
-
const get = require('simple-get').concat
|
|
11
11
|
const FormData = require('form-data')
|
|
12
12
|
|
|
13
13
|
const split = require('split2')
|
|
@@ -23,68 +23,62 @@ const instance = Fastify({
|
|
|
23
23
|
instance.register(Multipart)
|
|
24
24
|
instance.register(From)
|
|
25
25
|
|
|
26
|
-
t.
|
|
26
|
+
t.test('fastify-multipart-incompatibility', async (t) => {
|
|
27
|
+
t.plan(9)
|
|
27
28
|
|
|
28
|
-
t.
|
|
29
|
+
t.after(() => instance.close())
|
|
29
30
|
|
|
30
|
-
const filetPath = path.join(__dirname, 'fixtures', 'file.txt')
|
|
31
|
-
const fileContent = fs.readFileSync(filetPath, { encoding: 'utf-8' })
|
|
31
|
+
const filetPath = path.join(__dirname, 'fixtures', 'file.txt')
|
|
32
|
+
const fileContent = fs.readFileSync(filetPath, { encoding: 'utf-8' })
|
|
32
33
|
|
|
33
|
-
const target = http.createServer((req, res) => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
34
|
+
const target = http.createServer((req, res) => {
|
|
35
|
+
t.assert.ok('request proxied')
|
|
36
|
+
t.assert.strictEqual(req.method, 'POST')
|
|
37
|
+
t.assert.match(req.headers['content-type'], /^multipart\/form-data/)
|
|
38
|
+
let data = ''
|
|
39
|
+
req.setEncoding('utf8')
|
|
40
|
+
req.on('data', (d) => {
|
|
41
|
+
data += d
|
|
42
|
+
})
|
|
43
|
+
req.on('end', () => {
|
|
44
|
+
t.assert.notDeepEqual(data, 'Content-Disposition: form-data; name="key"')
|
|
45
|
+
t.assert.notDeepEqual(data, 'value')
|
|
46
|
+
t.assert.notDeepEqual(data, 'Content-Disposition: form-data; name="file"')
|
|
47
|
+
t.assert.notDeepEqual(data, fileContent)
|
|
48
|
+
res.setHeader('content-type', 'application/json')
|
|
49
|
+
res.statusCode = 200
|
|
50
|
+
res.end(JSON.stringify({ something: 'else' }))
|
|
51
|
+
})
|
|
50
52
|
})
|
|
51
|
-
})
|
|
52
53
|
|
|
53
|
-
instance.post('/', (_request, reply) => {
|
|
54
|
-
|
|
55
|
-
})
|
|
54
|
+
instance.post('/', (_request, reply) => {
|
|
55
|
+
reply.from(`http://localhost:${target.address().port}`)
|
|
56
|
+
})
|
|
56
57
|
|
|
57
|
-
t.
|
|
58
|
+
t.after(() => target.close())
|
|
58
59
|
|
|
59
|
-
instance.listen({ port: 0 },
|
|
60
|
-
t.error(err)
|
|
60
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
61
61
|
|
|
62
62
|
logStream.on('data', (log) => {
|
|
63
63
|
if (
|
|
64
64
|
log.level === 40 &&
|
|
65
65
|
log.msg.match(/@fastify\/reply-from might not behave as expected when used with @fastify\/multipart/)
|
|
66
66
|
) {
|
|
67
|
-
t.
|
|
67
|
+
t.assert.ok('incompatibility warn message logged')
|
|
68
68
|
}
|
|
69
69
|
})
|
|
70
70
|
|
|
71
|
-
target.listen({ port: 0 },
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
})
|
|
71
|
+
await new Promise(resolve => target.listen({ port: 0 }, resolve))
|
|
72
|
+
|
|
73
|
+
const form = new FormData()
|
|
74
|
+
form.append('key', 'value')
|
|
75
|
+
form.append('file', fs.createReadStream(filetPath, { encoding: 'utf-8' }))
|
|
76
|
+
|
|
77
|
+
const result = await request(`http://localhost:${instance.server.address().port}`, {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
headers: form.getHeaders(),
|
|
80
|
+
body: form
|
|
89
81
|
})
|
|
82
|
+
|
|
83
|
+
t.assert.deepStrictEqual(await result.body.json(), { something: 'else' })
|
|
90
84
|
})
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { describe, after, it } = require('node:test')
|
|
4
4
|
const fastify = require('fastify')
|
|
5
|
+
const { request } = require('undici')
|
|
5
6
|
const fastifyProxyFrom = require('..')
|
|
6
7
|
const { isIPv6 } = require('node:net')
|
|
7
8
|
|
|
@@ -49,7 +50,7 @@ describe('GHSA-v2v2-hph8-q5xp', function () {
|
|
|
49
50
|
appAddress = `[${appAddress}]`
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
const response = await
|
|
53
|
+
const response = await request(
|
|
53
54
|
`http://${appAddress}:${app.server.address().port}/test`,
|
|
54
55
|
{
|
|
55
56
|
headers: { 'content-type': 'application/json ; charset=utf-8' },
|
|
@@ -58,6 +59,6 @@ describe('GHSA-v2v2-hph8-q5xp', function () {
|
|
|
58
59
|
method: 'POST'
|
|
59
60
|
})
|
|
60
61
|
|
|
61
|
-
t.assert.strictEqual(await response.text(), 'ok')
|
|
62
|
+
t.assert.strictEqual(await response.body.text(), 'ok')
|
|
62
63
|
})
|
|
63
64
|
})
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { test } = require('
|
|
3
|
+
const { test } = require('node:test')
|
|
4
4
|
const Fastify = require('fastify')
|
|
5
|
+
const { request, Agent } = require('undici')
|
|
5
6
|
const From = require('..')
|
|
6
|
-
const got = require('got')
|
|
7
7
|
|
|
8
8
|
test('http -> http2', async function (t) {
|
|
9
9
|
const instance = Fastify()
|
|
10
10
|
|
|
11
|
-
t.
|
|
11
|
+
t.after(() => instance.close())
|
|
12
12
|
|
|
13
13
|
const target = Fastify({
|
|
14
14
|
http2: true
|
|
15
15
|
})
|
|
16
16
|
|
|
17
17
|
target.delete('/', (_request, reply) => {
|
|
18
|
-
t.
|
|
18
|
+
t.assert.ok('request proxied')
|
|
19
19
|
reply.code(200).header('x-my-header', 'hello!').send({
|
|
20
20
|
hello: 'world'
|
|
21
21
|
})
|
|
@@ -25,7 +25,7 @@ test('http -> http2', async function (t) {
|
|
|
25
25
|
reply.from()
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
-
t.
|
|
28
|
+
t.after(() => target.close())
|
|
29
29
|
|
|
30
30
|
await target.listen({ port: 0 })
|
|
31
31
|
|
|
@@ -36,17 +36,18 @@ test('http -> http2', async function (t) {
|
|
|
36
36
|
|
|
37
37
|
await instance.listen({ port: 0 })
|
|
38
38
|
|
|
39
|
-
const { headers, body, statusCode } = await
|
|
39
|
+
const { headers, body, statusCode } = await request(
|
|
40
40
|
`http://localhost:${instance.server.address().port}`,
|
|
41
41
|
{
|
|
42
42
|
method: 'DELETE',
|
|
43
|
-
responseType: 'json'
|
|
43
|
+
responseType: 'json',
|
|
44
|
+
dispatcher: new Agent({ pipelining: 0 })
|
|
44
45
|
}
|
|
45
46
|
)
|
|
46
|
-
t.
|
|
47
|
-
t.
|
|
48
|
-
t.match(headers['content-type'], /application\/json/)
|
|
49
|
-
t.
|
|
47
|
+
t.assert.strictEqual(statusCode, 200)
|
|
48
|
+
t.assert.strictEqual(headers['x-my-header'], 'hello!')
|
|
49
|
+
t.assert.match(headers['content-type'], /application\/json/)
|
|
50
|
+
t.assert.deepStrictEqual(await body.json(), { hello: 'world' })
|
|
50
51
|
instance.close()
|
|
51
52
|
target.close()
|
|
52
53
|
})
|
|
@@ -1,45 +1,42 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const t = require('
|
|
3
|
+
const t = require('node:test')
|
|
4
4
|
const Fastify = require('fastify')
|
|
5
|
+
const { request } = require('undici')
|
|
5
6
|
const From = require('..')
|
|
6
7
|
const http = require('node:http')
|
|
7
|
-
const get = require('simple-get').concat
|
|
8
8
|
|
|
9
9
|
const instance = Fastify()
|
|
10
10
|
instance.register(From)
|
|
11
11
|
|
|
12
|
-
t.
|
|
13
|
-
t.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
12
|
+
t.test('full get', async (t) => {
|
|
13
|
+
t.plan(7)
|
|
14
|
+
t.after(() => instance.close())
|
|
15
|
+
|
|
16
|
+
const target = http.createServer((req, res) => {
|
|
17
|
+
t.assert.ok('request proxied')
|
|
18
|
+
t.assert.strictEqual(req.method, 'GET')
|
|
19
|
+
t.assert.strictEqual(req.url, '/hello')
|
|
20
|
+
res.statusCode = 205
|
|
21
|
+
res.setHeader('Content-Type', 'text/plain')
|
|
22
|
+
res.setHeader('x-my-header', 'hello!')
|
|
23
|
+
res.end('hello world')
|
|
24
|
+
})
|
|
24
25
|
|
|
25
|
-
instance.get('/', (_request, reply) => {
|
|
26
|
-
|
|
27
|
-
})
|
|
26
|
+
instance.get('/', (_request, reply) => {
|
|
27
|
+
reply.from(`http://localhost:${target.address().port}/hello`)
|
|
28
|
+
})
|
|
28
29
|
|
|
29
|
-
t.
|
|
30
|
+
t.after(() => target.close())
|
|
30
31
|
|
|
31
|
-
instance.listen({ port: 0 },
|
|
32
|
-
t.error(err)
|
|
32
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
33
33
|
|
|
34
|
-
target.listen({ port: 0 },
|
|
35
|
-
t.error(err)
|
|
34
|
+
await new Promise(resolve => target.listen({ port: 0 }, resolve))
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
})
|
|
44
|
-
})
|
|
36
|
+
const result = await request(`http://localhost:${instance.server.address().port}`)
|
|
37
|
+
|
|
38
|
+
t.assert.strictEqual(result.headers['content-type'], 'text/plain')
|
|
39
|
+
t.assert.strictEqual(result.headers['x-my-header'], 'hello!')
|
|
40
|
+
t.assert.strictEqual(result.statusCode, 205)
|
|
41
|
+
t.assert.strictEqual(await result.body.text(), 'hello world')
|
|
45
42
|
})
|