@fastify/reply-from 12.0.2 → 12.2.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/workflows/ci.yml +6 -0
- package/CLAUDE.md +66 -0
- package/LICENSE +4 -1
- package/README.md +24 -0
- package/index.js +12 -1
- package/lib/request.js +16 -6
- 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 +87 -27
- package/test/http2-canceled-streams-cleanup.test.js +117 -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 +94 -43
- 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 +86 -23
- 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 +13 -5
- package/types/index.test-d.ts +6 -6
- package/test/get-with-body.test.js +0 -55
- package/test/head-with-body.test.js +0 -57
|
@@ -1,49 +1,43 @@
|
|
|
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
|
|
|
11
|
-
t.
|
|
12
|
-
t.
|
|
11
|
+
t.test('no body opts with get', async (t) => {
|
|
12
|
+
t.plan(3)
|
|
13
|
+
t.after(() => instance.close())
|
|
13
14
|
|
|
14
|
-
const target = http.createServer((_req, res) => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
})
|
|
15
|
+
const target = http.createServer((_req, res) => {
|
|
16
|
+
t.fail('this should never get called')
|
|
17
|
+
res.end('hello world')
|
|
18
|
+
})
|
|
18
19
|
|
|
19
|
-
instance.get('/', (_request, reply) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
})
|
|
20
|
+
instance.get('/', (_request, reply) => {
|
|
21
|
+
try {
|
|
22
|
+
reply.from(null, { body: 'this is the new body' })
|
|
23
|
+
} catch (e) {
|
|
24
|
+
t.assert.strictEqual(e.message, 'Rewriting the body when doing a GET is not allowed')
|
|
25
|
+
reply.send('hello world')
|
|
26
|
+
}
|
|
27
|
+
})
|
|
27
28
|
|
|
28
|
-
t.
|
|
29
|
+
t.after(() => target.close())
|
|
29
30
|
|
|
30
|
-
target.listen({ port: 0 },
|
|
31
|
-
t.error(err)
|
|
31
|
+
await new Promise(resolve => target.listen({ port: 0 }, resolve))
|
|
32
32
|
|
|
33
33
|
instance.register(From, {
|
|
34
34
|
base: `http://localhost:${target.address().port}`
|
|
35
35
|
})
|
|
36
36
|
|
|
37
|
-
instance.listen({ port: 0 },
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}, (err, res, data) => {
|
|
44
|
-
t.error(err)
|
|
45
|
-
t.equal(res.statusCode, 200)
|
|
46
|
-
t.equal(data.toString(), 'hello world')
|
|
47
|
-
})
|
|
48
|
-
})
|
|
37
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
38
|
+
|
|
39
|
+
const result = await request(`http://localhost:${instance.server.address().port}`)
|
|
40
|
+
|
|
41
|
+
t.assert.strictEqual(result.statusCode, 200)
|
|
42
|
+
t.assert.strictEqual(await result.body.text(), 'hello world')
|
|
49
43
|
})
|
|
@@ -1,51 +1,47 @@
|
|
|
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
|
|
|
11
|
-
t.
|
|
12
|
-
t.
|
|
11
|
+
t.test('no body opts with head', async (t) => {
|
|
12
|
+
t.plan(4)
|
|
13
|
+
t.after(() => instance.close())
|
|
13
14
|
|
|
14
|
-
const target = http.createServer((_req, res) => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
})
|
|
15
|
+
const target = http.createServer((_req, res) => {
|
|
16
|
+
t.fail('this should never get called')
|
|
17
|
+
res.end('hello world')
|
|
18
|
+
})
|
|
18
19
|
|
|
19
|
-
instance.head('/', (_request, reply) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
})
|
|
20
|
+
instance.head('/', (_request, reply) => {
|
|
21
|
+
try {
|
|
22
|
+
reply.from(null, { body: 'this is the new body' })
|
|
23
|
+
} catch (e) {
|
|
24
|
+
t.assert.strictEqual(e.message, 'Rewriting the body when doing a HEAD is not allowed')
|
|
25
|
+
reply.header('x-http-error', '1')
|
|
26
|
+
reply.send('hello world')
|
|
27
|
+
}
|
|
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}`
|
|
36
36
|
})
|
|
37
37
|
|
|
38
|
-
instance.listen({ port: 0 },
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
url: `http://localhost:${instance.server.address().port}`,
|
|
43
|
-
method: 'HEAD'
|
|
44
|
-
}, (err, res, data) => {
|
|
45
|
-
t.error(err)
|
|
46
|
-
t.equal(res.statusCode, 200)
|
|
47
|
-
t.equal(res.headers['x-http-error'], '1')
|
|
48
|
-
t.equal(data.toString(), '')
|
|
49
|
-
})
|
|
38
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
39
|
+
|
|
40
|
+
const result = await request(`http://localhost:${instance.server.address().port}`, {
|
|
41
|
+
method: 'HEAD'
|
|
50
42
|
})
|
|
43
|
+
|
|
44
|
+
t.assert.strictEqual(result.statusCode, 200)
|
|
45
|
+
t.assert.strictEqual(result.headers['x-http-error'], '1')
|
|
46
|
+
t.assert.strictEqual(await result.body.text(), '')
|
|
51
47
|
})
|
|
@@ -1,58 +1,56 @@
|
|
|
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
|
const Readable = require('node:stream').Readable
|
|
9
9
|
|
|
10
10
|
const instance = Fastify()
|
|
11
11
|
instance.register(From)
|
|
12
12
|
|
|
13
|
-
t.
|
|
14
|
-
t.
|
|
13
|
+
t.test('no stream body option', async (t) => {
|
|
14
|
+
t.plan(2)
|
|
15
|
+
t.after(() => instance.close())
|
|
15
16
|
|
|
16
|
-
const target = http.createServer((_req, res) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
instance.post('/', (_request, reply) => {
|
|
22
|
-
const body = new Readable({
|
|
23
|
-
read: function () {
|
|
24
|
-
t.fail('the read function should never be called')
|
|
25
|
-
}
|
|
17
|
+
const target = http.createServer((_req, res) => {
|
|
18
|
+
t.fail('the target server should never be called')
|
|
19
|
+
res.end()
|
|
26
20
|
})
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
instance.post('/', (_request, reply) => {
|
|
23
|
+
const body = new Readable({
|
|
24
|
+
read: function () {
|
|
25
|
+
t.fail('the read function should never be called')
|
|
26
|
+
}
|
|
31
27
|
})
|
|
32
|
-
})
|
|
33
28
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
t.assert.throws(() => {
|
|
30
|
+
reply.from(`http://localhost:${target.address().port}`, {
|
|
31
|
+
body
|
|
32
|
+
})
|
|
33
|
+
})
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
// return a 500
|
|
36
|
+
reply.code(500).send({ an: 'error' })
|
|
37
|
+
})
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
t.error(err)
|
|
39
|
+
t.after(() => target.close())
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
t.error(err)
|
|
41
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
45
42
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
t.equal(res.statusCode, 500)
|
|
43
|
+
await new Promise(resolve => target.listen({ port: 0 }, resolve))
|
|
44
|
+
|
|
45
|
+
const result = await request(`http://localhost:${instance.server.address().port}`, {
|
|
46
|
+
method: 'POST',
|
|
47
|
+
headers: {
|
|
48
|
+
'content-type': 'application/json'
|
|
49
|
+
},
|
|
50
|
+
body: JSON.stringify({
|
|
51
|
+
hello: 'world'
|
|
56
52
|
})
|
|
57
53
|
})
|
|
54
|
+
|
|
55
|
+
t.assert.strictEqual(result.statusCode, 500)
|
|
58
56
|
})
|
package/test/on-error.test.js
CHANGED
|
@@ -1,64 +1,62 @@
|
|
|
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
|
-
const got = require('got')
|
|
7
7
|
const FakeTimers = require('@sinonjs/fake-timers')
|
|
8
8
|
|
|
9
9
|
const clock = FakeTimers.createClock()
|
|
10
10
|
|
|
11
11
|
t.test('on-error', async (t) => {
|
|
12
12
|
const target = Fastify()
|
|
13
|
-
t.
|
|
13
|
+
t.after(() => target.close())
|
|
14
14
|
|
|
15
15
|
target.get('/', (_request, reply) => {
|
|
16
|
-
t.
|
|
16
|
+
t.assert.ok('request arrives')
|
|
17
17
|
|
|
18
18
|
clock.setTimeout(() => {
|
|
19
19
|
reply.status(200).send('hello world')
|
|
20
|
-
t.end()
|
|
21
20
|
}, 1000)
|
|
22
21
|
})
|
|
23
22
|
|
|
24
23
|
await target.listen({ port: 0 })
|
|
25
24
|
|
|
26
25
|
const instance = Fastify()
|
|
27
|
-
t.
|
|
26
|
+
t.after(() => instance.close())
|
|
28
27
|
|
|
29
28
|
instance.register(From, { http: { requestOptions: { timeout: 100 } } })
|
|
30
29
|
|
|
31
30
|
instance.get('/', (_request, reply) => {
|
|
32
31
|
reply.from(`http://localhost:${target.server.address().port}/`,
|
|
33
32
|
{
|
|
34
|
-
onError: (reply, { error }) => {
|
|
35
|
-
t.
|
|
33
|
+
onError: (reply, { error: { stack, ...errorContent } }) => {
|
|
34
|
+
t.assert.deepStrictEqual(errorContent, {
|
|
36
35
|
statusCode: 504,
|
|
37
36
|
name: 'FastifyError',
|
|
38
37
|
code: 'FST_REPLY_FROM_GATEWAY_TIMEOUT',
|
|
39
38
|
message: 'Gateway Timeout'
|
|
40
39
|
})
|
|
41
|
-
reply.code(
|
|
40
|
+
reply.code(errorContent.statusCode).send(errorContent)
|
|
42
41
|
}
|
|
43
42
|
})
|
|
44
43
|
})
|
|
45
44
|
|
|
46
45
|
await instance.listen({ port: 0 })
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
t.equal(err.response.statusCode, 504)
|
|
52
|
-
t.match(err.response.headers['content-type'], /application\/json/)
|
|
53
|
-
t.same(JSON.parse(err.response.body), {
|
|
54
|
-
statusCode: 504,
|
|
55
|
-
code: 'FST_REPLY_FROM_GATEWAY_TIMEOUT',
|
|
56
|
-
error: 'Gateway Timeout',
|
|
57
|
-
message: 'Gateway Timeout'
|
|
47
|
+
const result = await request(`http://localhost:${instance.server.address().port}/`, {
|
|
48
|
+
dispatcher: new Agent({
|
|
49
|
+
pipelining: 0
|
|
58
50
|
})
|
|
59
|
-
|
|
60
|
-
return
|
|
61
|
-
}
|
|
51
|
+
})
|
|
62
52
|
|
|
63
|
-
t.
|
|
53
|
+
t.assert.strictEqual(result.statusCode, 504)
|
|
54
|
+
t.assert.match(result.headers['content-type'], /application\/json/)
|
|
55
|
+
t.assert.deepStrictEqual(await result.body.json(), {
|
|
56
|
+
statusCode: 504,
|
|
57
|
+
code: 'FST_REPLY_FROM_GATEWAY_TIMEOUT',
|
|
58
|
+
name: 'FastifyError',
|
|
59
|
+
message: 'Gateway Timeout'
|
|
60
|
+
})
|
|
61
|
+
clock.tick(1000)
|
|
64
62
|
})
|
|
@@ -1,52 +1,45 @@
|
|
|
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.
|
|
12
|
+
t.test('on-invalid-upstream-response', async (t) => {
|
|
13
|
+
t.plan(5)
|
|
14
|
+
t.after(() => instance.close())
|
|
14
15
|
|
|
15
|
-
const target = http.createServer((req, res) => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
instance.get('/', (_, reply) => {
|
|
23
|
-
reply.from(`http://localhost:${target.address().port}`, {
|
|
24
|
-
onResponse: (_, _reply, res) => {
|
|
25
|
-
t.equal(res.statusCode, 888)
|
|
26
|
-
}
|
|
16
|
+
const target = http.createServer((req, res) => {
|
|
17
|
+
t.assert.ok('request proxied')
|
|
18
|
+
t.assert.strictEqual(req.method, 'GET')
|
|
19
|
+
res.statusCode = 888
|
|
20
|
+
res.end('non-standard status code')
|
|
27
21
|
})
|
|
28
|
-
})
|
|
29
22
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
target.listen({ port: 0 }, (err) => {
|
|
36
|
-
t.error(err)
|
|
37
|
-
|
|
38
|
-
get(
|
|
39
|
-
`http://localhost:${instance.server.address().port}`,
|
|
40
|
-
(err, res, data) => {
|
|
41
|
-
t.error(err)
|
|
42
|
-
t.equal(res.statusCode, 502)
|
|
43
|
-
t.same(JSON.parse(data), {
|
|
44
|
-
statusCode: 502,
|
|
45
|
-
code: 'FST_REPLY_FROM_BAD_GATEWAY',
|
|
46
|
-
error: 'Bad Gateway',
|
|
47
|
-
message: 'Bad Gateway'
|
|
48
|
-
})
|
|
23
|
+
instance.get('/', (_, reply) => {
|
|
24
|
+
reply.from(`http://localhost:${target.address().port}`, {
|
|
25
|
+
onResponse: (_, _reply, res) => {
|
|
26
|
+
t.assert.strictEqual(res.statusCode, 888)
|
|
49
27
|
}
|
|
50
|
-
)
|
|
28
|
+
})
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
t.after(() => target.close())
|
|
32
|
+
|
|
33
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
34
|
+
|
|
35
|
+
await new Promise(resolve => target.listen({ port: 0 }, resolve))
|
|
36
|
+
|
|
37
|
+
const result = await request(`http://localhost:${instance.server.address().port}`)
|
|
38
|
+
t.assert.strictEqual(result.statusCode, 502)
|
|
39
|
+
t.assert.deepStrictEqual(await result.body.json(), {
|
|
40
|
+
statusCode: 502,
|
|
41
|
+
code: 'FST_REPLY_FROM_BAD_GATEWAY',
|
|
42
|
+
error: 'Bad Gateway',
|
|
43
|
+
message: 'Bad Gateway'
|
|
51
44
|
})
|
|
52
45
|
})
|
package/test/onResponse.test.js
CHANGED
|
@@ -1,49 +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.
|
|
12
|
+
t.test('onResponse', async (t) => {
|
|
13
|
+
t.plan(6)
|
|
14
|
+
t.after(() => instance.close())
|
|
14
15
|
|
|
15
|
-
const target = http.createServer((req, res) => {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
})
|
|
16
|
+
const target = http.createServer((req, res) => {
|
|
17
|
+
t.assert.ok('request proxied')
|
|
18
|
+
t.assert.strictEqual(req.method, 'GET')
|
|
19
|
+
res.statusCode = 200
|
|
20
|
+
res.end('hello world')
|
|
21
|
+
})
|
|
21
22
|
|
|
22
|
-
instance.get('/', (request1, reply) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
instance.get('/', (request1, reply) => {
|
|
24
|
+
reply.from(`http://localhost:${target.address().port}`, {
|
|
25
|
+
onResponse: (request2, reply, res) => {
|
|
26
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
27
|
+
t.assert.strictEqual(request1.raw, request2.raw)
|
|
28
|
+
reply.send(res.stream)
|
|
29
|
+
}
|
|
30
|
+
})
|
|
29
31
|
})
|
|
30
|
-
})
|
|
31
32
|
|
|
32
|
-
t.
|
|
33
|
+
t.after(() => target.close())
|
|
33
34
|
|
|
34
|
-
instance.listen({ port: 0 },
|
|
35
|
-
t.error(err)
|
|
35
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
36
36
|
|
|
37
|
-
target.listen({ port: 0 },
|
|
38
|
-
t.error(err)
|
|
37
|
+
await new Promise(resolve => target.listen({ port: 0 }, resolve))
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
t.error(err)
|
|
44
|
-
t.equal(res.statusCode, 200)
|
|
45
|
-
t.equal(data.toString(), 'hello world')
|
|
46
|
-
}
|
|
47
|
-
)
|
|
48
|
-
})
|
|
39
|
+
const result = await request(`http://localhost:${instance.server.address().port}`)
|
|
40
|
+
t.assert.strictEqual(result.statusCode, 200)
|
|
41
|
+
t.assert.strictEqual(await result.body.text(), 'hello world')
|
|
49
42
|
})
|
package/test/padded-body.test.js
CHANGED
|
@@ -1,64 +1,59 @@
|
|
|
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.
|
|
12
|
+
t.test('padded body', async (t) => {
|
|
13
|
+
t.plan(6)
|
|
14
|
+
t.after(() => instance.close())
|
|
14
15
|
|
|
15
|
-
const bodyString = `{
|
|
16
|
+
const bodyString = `{
|
|
16
17
|
"hello": "world"
|
|
17
18
|
}`
|
|
18
19
|
|
|
19
|
-
const parsedLength = Buffer.byteLength(JSON.stringify(JSON.parse(bodyString)))
|
|
20
|
-
|
|
21
|
-
const target = http.createServer((req, res) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
20
|
+
const parsedLength = Buffer.byteLength(JSON.stringify(JSON.parse(bodyString)))
|
|
21
|
+
|
|
22
|
+
const target = http.createServer((req, res) => {
|
|
23
|
+
t.assert.ok('request proxied')
|
|
24
|
+
t.assert.strictEqual(req.method, 'POST')
|
|
25
|
+
t.assert.strictEqual(req.headers['content-type'], 'application/json')
|
|
26
|
+
t.assert.deepStrictEqual(req.headers['content-length'], `${parsedLength}`)
|
|
27
|
+
let data = ''
|
|
28
|
+
req.setEncoding('utf8')
|
|
29
|
+
req.on('data', (d) => {
|
|
30
|
+
data += d
|
|
31
|
+
})
|
|
32
|
+
req.on('end', () => {
|
|
33
|
+
t.assert.deepStrictEqual(JSON.parse(data), { hello: 'world' })
|
|
34
|
+
res.statusCode = 200
|
|
35
|
+
res.setHeader('content-type', 'application/json')
|
|
36
|
+
res.end(JSON.stringify({ something: 'else' }))
|
|
37
|
+
})
|
|
36
38
|
})
|
|
37
|
-
})
|
|
38
39
|
|
|
39
|
-
instance.post('/', (_request, reply) => {
|
|
40
|
-
|
|
41
|
-
})
|
|
40
|
+
instance.post('/', (_request, reply) => {
|
|
41
|
+
reply.from(`http://localhost:${target.address().port}`)
|
|
42
|
+
})
|
|
42
43
|
|
|
43
|
-
t.
|
|
44
|
+
t.after(() => target.close())
|
|
44
45
|
|
|
45
|
-
instance.listen({ port: 0 },
|
|
46
|
-
t.error(err)
|
|
46
|
+
await new Promise(resolve => instance.listen({ port: 0 }, resolve))
|
|
47
47
|
|
|
48
|
-
target.listen({ port: 0 },
|
|
49
|
-
t.error(err)
|
|
48
|
+
await new Promise(resolve => target.listen({ port: 0 }, resolve))
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
body: bodyString
|
|
58
|
-
}, (err, _res, data) => {
|
|
59
|
-
t.error(err)
|
|
60
|
-
const parsed = JSON.parse(data)
|
|
61
|
-
t.same(parsed, { something: 'else' })
|
|
62
|
-
})
|
|
50
|
+
const result = await request(`http://localhost:${instance.server.address().port}`, {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
headers: {
|
|
53
|
+
'content-type': 'application/json'
|
|
54
|
+
},
|
|
55
|
+
body: bodyString
|
|
63
56
|
})
|
|
57
|
+
|
|
58
|
+
t.assert.deepStrictEqual(await result.body.json(), { something: 'else' })
|
|
64
59
|
})
|