fastify 5.3.2 → 5.4.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/README.md +2 -0
- package/build/build-validation.js +2 -1
- package/docs/Guides/Delay-Accepting-Requests.md +3 -3
- package/docs/Guides/Ecosystem.md +16 -7
- package/docs/Guides/Serverless.md +28 -69
- package/docs/Reference/ContentTypeParser.md +1 -1
- package/docs/Reference/Errors.md +2 -4
- package/docs/Reference/Hooks.md +14 -14
- package/docs/Reference/Logging.md +3 -3
- package/docs/Reference/Middleware.md +1 -1
- package/docs/Reference/Reply.md +8 -8
- package/docs/Reference/Request.md +1 -1
- package/docs/Reference/Routes.md +3 -3
- package/docs/Reference/Server.md +40 -10
- package/docs/Reference/Validation-and-Serialization.md +1 -1
- package/eslint.config.js +17 -9
- package/fastify.d.ts +2 -1
- package/fastify.js +20 -4
- package/lib/configValidator.js +1 -1
- package/lib/decorate.js +2 -2
- package/lib/errors.js +6 -8
- package/lib/logger-factory.js +1 -1
- package/lib/logger-pino.js +2 -2
- package/lib/pluginOverride.js +3 -1
- package/lib/reply.js +9 -13
- package/lib/request.js +4 -11
- package/lib/server.js +30 -51
- package/lib/symbols.js +1 -0
- package/lib/warnings.js +8 -0
- package/package.json +11 -7
- package/test/404s.test.js +226 -325
- package/test/allow-unsafe-regex.test.js +19 -48
- package/test/als.test.js +28 -40
- package/test/async-await.test.js +11 -2
- package/test/body-limit.test.js +41 -65
- package/test/build-certificate.js +1 -1
- package/test/close-pipelining.test.js +5 -4
- package/test/custom-parser-async.test.js +17 -22
- package/test/decorator-namespace.test._js_ +3 -4
- package/test/decorator.test.js +422 -341
- package/test/diagnostics-channel/async-delay-request.test.js +7 -16
- package/test/diagnostics-channel/sync-delay-request.test.js +7 -16
- package/test/helper.js +108 -70
- package/test/hooks-async.test.js +248 -218
- package/test/hooks.on-listen.test.js +255 -239
- package/test/hooks.on-ready.test.js +110 -92
- package/test/hooks.test.js +910 -769
- package/test/http-methods/lock.test.js +31 -31
- package/test/http-methods/mkcol.test.js +5 -9
- package/test/http-methods/proppatch.test.js +23 -29
- package/test/http-methods/report.test.js +44 -69
- package/test/http-methods/search.test.js +67 -82
- package/test/http2/closing.test.js +38 -20
- package/test/http2/secure-with-fallback.test.js +28 -27
- package/test/https/https.test.js +56 -53
- package/test/inject.test.js +114 -97
- package/test/input-validation.js +63 -53
- package/test/internals/errors.test.js +0 -10
- package/test/internals/handle-request.test.js +49 -66
- package/test/internals/hooks.test.js +17 -0
- package/test/issue-4959.test.js +14 -5
- package/test/listen.4.test.js +31 -43
- package/test/logger/response.test.js +19 -20
- package/test/nullable-validation.test.js +33 -46
- package/test/options.error-handler.test.js +1 -1
- package/test/options.test.js +1 -1
- package/test/output-validation.test.js +49 -72
- package/test/patch.error-handler.test.js +1 -1
- package/test/patch.test.js +1 -1
- package/test/plugin.1.test.js +71 -60
- package/test/plugin.2.test.js +104 -86
- package/test/plugin.3.test.js +56 -35
- package/test/plugin.4.test.js +124 -119
- package/test/promises.test.js +36 -30
- package/test/proto-poisoning.test.js +78 -97
- package/test/put.error-handler.test.js +1 -1
- package/test/put.test.js +1 -1
- package/test/reply-error.test.js +169 -148
- package/test/reply-trailers.test.js +119 -108
- package/test/request-error.test.js +0 -46
- package/test/route-hooks.test.js +112 -92
- package/test/route-prefix.test.js +194 -133
- package/test/schema-feature.test.js +309 -238
- package/test/schema-serialization.test.js +177 -154
- package/test/schema-special-usage.test.js +165 -132
- package/test/schema-validation.test.js +278 -199
- package/test/set-error-handler.test.js +58 -1
- package/test/skip-reply-send.test.js +64 -69
- package/test/stream.1.test.js +30 -27
- package/test/stream.2.test.js +20 -10
- package/test/stream.3.test.js +37 -31
- package/test/trust-proxy.test.js +32 -58
- package/test/types/errors.test-d.ts +0 -1
- package/test/types/fastify.test-d.ts +3 -0
- package/test/types/plugin.test-d.ts +1 -1
- package/test/types/register.test-d.ts +1 -1
- package/test/types/request.test-d.ts +1 -0
- package/test/url-rewriting.test.js +45 -62
- package/test/use-semicolon-delimiter.test.js +1 -1
- package/types/errors.d.ts +0 -1
- package/types/request.d.ts +1 -0
- package/.taprc +0 -7
- package/test/http2/missing-http2-module.test.js +0 -17
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
4
|
const Fastify = require('..')
|
|
5
|
-
const { FST_ERR_ERROR_HANDLER_NOT_FN } = require('../lib/errors')
|
|
5
|
+
const { FST_ERR_ERROR_HANDLER_NOT_FN, FST_ERR_ERROR_HANDLER_ALREADY_SET } = require('../lib/errors')
|
|
6
6
|
|
|
7
7
|
test('setErrorHandler should throw an error if the handler is not a function', t => {
|
|
8
8
|
t.plan(1)
|
|
@@ -10,3 +10,60 @@ test('setErrorHandler should throw an error if the handler is not a function', t
|
|
|
10
10
|
|
|
11
11
|
t.assert.throws(() => fastify.setErrorHandler('not a function'), new FST_ERR_ERROR_HANDLER_NOT_FN())
|
|
12
12
|
})
|
|
13
|
+
|
|
14
|
+
test('setErrorHandler can be set independently in parent and child scopes', async t => {
|
|
15
|
+
t.plan(1)
|
|
16
|
+
|
|
17
|
+
const fastify = Fastify()
|
|
18
|
+
|
|
19
|
+
t.assert.doesNotThrow(() => {
|
|
20
|
+
fastify.setErrorHandler(() => {})
|
|
21
|
+
fastify.register(async (child) => {
|
|
22
|
+
child.setErrorHandler(() => {})
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
test('setErrorHandler can be overriden if allowErrorHandlerOverride is set to true', async t => {
|
|
28
|
+
t.plan(2)
|
|
29
|
+
|
|
30
|
+
const fastify = Fastify()
|
|
31
|
+
t.after(() => fastify.close())
|
|
32
|
+
|
|
33
|
+
fastify.register(async (child) => {
|
|
34
|
+
child.setErrorHandler(() => {})
|
|
35
|
+
t.assert.doesNotThrow(() => child.setErrorHandler(() => {}))
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
fastify.setErrorHandler(() => {})
|
|
39
|
+
t.assert.doesNotThrow(() => fastify.setErrorHandler(() => {}))
|
|
40
|
+
|
|
41
|
+
await fastify.ready()
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test('if `allowErrorHandlerOverride` is disabled, setErrorHandler should throw if called more than once in the same scope', t => {
|
|
45
|
+
t.plan(1)
|
|
46
|
+
|
|
47
|
+
const fastify = Fastify({
|
|
48
|
+
allowErrorHandlerOverride: false
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
fastify.setErrorHandler(() => {})
|
|
52
|
+
t.assert.throws(() => fastify.setErrorHandler(() => {}), new FST_ERR_ERROR_HANDLER_ALREADY_SET())
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
test('if `allowErrorHandlerOverride` is disabled, setErrorHandler should throw if called more than once in the same scope 2', async t => {
|
|
56
|
+
t.plan(1)
|
|
57
|
+
|
|
58
|
+
const fastify = Fastify({
|
|
59
|
+
allowErrorHandlerOverride: false
|
|
60
|
+
})
|
|
61
|
+
t.after(() => fastify.close())
|
|
62
|
+
|
|
63
|
+
fastify.register(async (child) => {
|
|
64
|
+
child.setErrorHandler(() => {})
|
|
65
|
+
t.assert.throws(() => child.setErrorHandler(() => {}), new FST_ERR_ERROR_HANDLER_ALREADY_SET())
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
await fastify.ready()
|
|
69
|
+
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { test } = require('
|
|
3
|
+
const { test, describe } = require('node:test')
|
|
4
4
|
const split = require('split2')
|
|
5
5
|
const net = require('node:net')
|
|
6
6
|
const Fastify = require('../fastify')
|
|
@@ -19,7 +19,7 @@ const lifecycleHooks = [
|
|
|
19
19
|
'onError'
|
|
20
20
|
]
|
|
21
21
|
|
|
22
|
-
test('skip automatic reply.send() with reply.hijack and a body', (t) => {
|
|
22
|
+
test('skip automatic reply.send() with reply.hijack and a body', async (t) => {
|
|
23
23
|
const stream = split(JSON.parse)
|
|
24
24
|
const app = Fastify({
|
|
25
25
|
logger: {
|
|
@@ -28,8 +28,8 @@ test('skip automatic reply.send() with reply.hijack and a body', (t) => {
|
|
|
28
28
|
})
|
|
29
29
|
|
|
30
30
|
stream.on('data', (line) => {
|
|
31
|
-
t.
|
|
32
|
-
t.
|
|
31
|
+
t.assert.notStrictEqual(line.level, 40) // there are no errors
|
|
32
|
+
t.assert.notStrictEqual(line.level, 50) // there are no errors
|
|
33
33
|
})
|
|
34
34
|
|
|
35
35
|
app.get('/', (req, reply) => {
|
|
@@ -39,16 +39,16 @@ test('skip automatic reply.send() with reply.hijack and a body', (t) => {
|
|
|
39
39
|
return Promise.resolve('this will be skipped')
|
|
40
40
|
})
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
await app.inject({
|
|
43
43
|
method: 'GET',
|
|
44
44
|
url: '/'
|
|
45
45
|
}).then((res) => {
|
|
46
|
-
t.
|
|
47
|
-
t.
|
|
46
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
47
|
+
t.assert.strictEqual(res.body, 'hello world')
|
|
48
48
|
})
|
|
49
49
|
})
|
|
50
50
|
|
|
51
|
-
test('skip automatic reply.send() with reply.hijack and no body', (t) => {
|
|
51
|
+
test('skip automatic reply.send() with reply.hijack and no body', async (t) => {
|
|
52
52
|
const stream = split(JSON.parse)
|
|
53
53
|
const app = Fastify({
|
|
54
54
|
logger: {
|
|
@@ -57,8 +57,8 @@ test('skip automatic reply.send() with reply.hijack and no body', (t) => {
|
|
|
57
57
|
})
|
|
58
58
|
|
|
59
59
|
stream.on('data', (line) => {
|
|
60
|
-
t.
|
|
61
|
-
t.
|
|
60
|
+
t.assert.notStrictEqual(line.level, 40) // there are no error
|
|
61
|
+
t.assert.notStrictEqual(line.level, 50) // there are no error
|
|
62
62
|
})
|
|
63
63
|
|
|
64
64
|
app.get('/', (req, reply) => {
|
|
@@ -68,16 +68,16 @@ test('skip automatic reply.send() with reply.hijack and no body', (t) => {
|
|
|
68
68
|
return Promise.resolve()
|
|
69
69
|
})
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
await app.inject({
|
|
72
72
|
method: 'GET',
|
|
73
73
|
url: '/'
|
|
74
74
|
}).then((res) => {
|
|
75
|
-
t.
|
|
76
|
-
t.
|
|
75
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
76
|
+
t.assert.strictEqual(res.body, 'hello world')
|
|
77
77
|
})
|
|
78
78
|
})
|
|
79
79
|
|
|
80
|
-
test('skip automatic reply.send() with reply.hijack and an error', (t) => {
|
|
80
|
+
test('skip automatic reply.send() with reply.hijack and an error', async (t) => {
|
|
81
81
|
const stream = split(JSON.parse)
|
|
82
82
|
const app = Fastify({
|
|
83
83
|
logger: {
|
|
@@ -90,8 +90,8 @@ test('skip automatic reply.send() with reply.hijack and an error', (t) => {
|
|
|
90
90
|
stream.on('data', (line) => {
|
|
91
91
|
if (line.level === 50) {
|
|
92
92
|
errorSeen = true
|
|
93
|
-
t.
|
|
94
|
-
t.
|
|
93
|
+
t.assert.strictEqual(line.err.message, 'kaboom')
|
|
94
|
+
t.assert.strictEqual(line.msg, 'Promise errored, but reply.sent = true was set')
|
|
95
95
|
}
|
|
96
96
|
})
|
|
97
97
|
|
|
@@ -102,13 +102,13 @@ test('skip automatic reply.send() with reply.hijack and an error', (t) => {
|
|
|
102
102
|
return Promise.reject(new Error('kaboom'))
|
|
103
103
|
})
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
await app.inject({
|
|
106
106
|
method: 'GET',
|
|
107
107
|
url: '/'
|
|
108
108
|
}).then((res) => {
|
|
109
|
-
t.
|
|
110
|
-
t.
|
|
111
|
-
t.
|
|
109
|
+
t.assert.strictEqual(errorSeen, true)
|
|
110
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
111
|
+
t.assert.strictEqual(res.body, 'hello world')
|
|
112
112
|
})
|
|
113
113
|
})
|
|
114
114
|
|
|
@@ -117,11 +117,8 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
|
|
|
117
117
|
const previousHooks = lifecycleHooks.slice(0, idx)
|
|
118
118
|
const nextHooks = lifecycleHooks.slice(idx + 1)
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const test = t.test
|
|
123
|
-
|
|
124
|
-
test('Sending a response using reply.raw => onResponse hook is called', t => {
|
|
120
|
+
describe(`Hijacking inside ${hookOrHandler} skips all the following hooks and handler execution`, () => {
|
|
121
|
+
test('Sending a response using reply.raw => onResponse hook is called', async (t) => {
|
|
125
122
|
const stream = split(JSON.parse)
|
|
126
123
|
const app = Fastify({
|
|
127
124
|
logger: {
|
|
@@ -130,11 +127,11 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
|
|
|
130
127
|
})
|
|
131
128
|
|
|
132
129
|
stream.on('data', (line) => {
|
|
133
|
-
t.
|
|
134
|
-
t.
|
|
130
|
+
t.assert.notStrictEqual(line.level, 40) // there are no errors
|
|
131
|
+
t.assert.notStrictEqual(line.level, 50) // there are no errors
|
|
135
132
|
})
|
|
136
133
|
|
|
137
|
-
previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.
|
|
134
|
+
previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.ok(`${h} should be called`)))
|
|
138
135
|
|
|
139
136
|
if (hookOrHandler === 'handler') {
|
|
140
137
|
app.get('/', (req, reply) => {
|
|
@@ -146,41 +143,41 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
|
|
|
146
143
|
reply.hijack()
|
|
147
144
|
reply.raw.end(`hello from ${hookOrHandler}`)
|
|
148
145
|
})
|
|
149
|
-
app.get('/', (req, reply) => t.fail('Handler should not be called'))
|
|
146
|
+
app.get('/', (req, reply) => t.assert.fail('Handler should not be called'))
|
|
150
147
|
}
|
|
151
148
|
|
|
152
149
|
nextHooks.forEach(h => {
|
|
153
150
|
if (h === 'onResponse') {
|
|
154
|
-
app.addHook(h, async (req, reply) => t.
|
|
151
|
+
app.addHook(h, async (req, reply) => t.assert.ok(`${h} should be called`))
|
|
155
152
|
} else {
|
|
156
|
-
app.addHook(h, async (req, reply) => t.fail(`${h} should not be called`))
|
|
153
|
+
app.addHook(h, async (req, reply) => t.assert.fail(`${h} should not be called`))
|
|
157
154
|
}
|
|
158
155
|
})
|
|
159
156
|
|
|
160
|
-
|
|
157
|
+
await app.inject({
|
|
161
158
|
method: 'GET',
|
|
162
159
|
url: '/'
|
|
163
160
|
}).then((res) => {
|
|
164
|
-
t.
|
|
165
|
-
t.
|
|
161
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
162
|
+
t.assert.strictEqual(res.body, `hello from ${hookOrHandler}`)
|
|
166
163
|
})
|
|
167
164
|
})
|
|
168
165
|
|
|
169
|
-
test('Sending a response using req.socket => onResponse not called', t => {
|
|
166
|
+
test('Sending a response using req.socket => onResponse not called', (t, testDone) => {
|
|
170
167
|
const stream = split(JSON.parse)
|
|
171
168
|
const app = Fastify({
|
|
172
169
|
logger: {
|
|
173
170
|
stream
|
|
174
171
|
}
|
|
175
172
|
})
|
|
176
|
-
t.
|
|
173
|
+
t.after(() => app.close())
|
|
177
174
|
|
|
178
175
|
stream.on('data', (line) => {
|
|
179
|
-
t.
|
|
180
|
-
t.
|
|
176
|
+
t.assert.notStrictEqual(line.level, 40) // there are no errors
|
|
177
|
+
t.assert.notStrictEqual(line.level, 50) // there are no errors
|
|
181
178
|
})
|
|
182
179
|
|
|
183
|
-
previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.
|
|
180
|
+
previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.ok(`${h} should be called`)))
|
|
184
181
|
|
|
185
182
|
if (hookOrHandler === 'handler') {
|
|
186
183
|
app.get('/', (req, reply) => {
|
|
@@ -196,13 +193,13 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
|
|
|
196
193
|
req.socket.write(`hello from ${hookOrHandler}`)
|
|
197
194
|
req.socket.end()
|
|
198
195
|
})
|
|
199
|
-
app.get('/', (req, reply) => t.fail('Handler should not be called'))
|
|
196
|
+
app.get('/', (req, reply) => t.assert.fail('Handler should not be called'))
|
|
200
197
|
}
|
|
201
198
|
|
|
202
|
-
nextHooks.forEach(h => app.addHook(h, async (req, reply) => t.fail(`${h} should not be called`)))
|
|
199
|
+
nextHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.fail(`${h} should not be called`)))
|
|
203
200
|
|
|
204
201
|
app.listen({ port: 0 }, err => {
|
|
205
|
-
t.
|
|
202
|
+
t.assert.ifError(err)
|
|
206
203
|
const client = net.createConnection({ port: (app.server.address()).port }, () => {
|
|
207
204
|
client.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n')
|
|
208
205
|
|
|
@@ -213,36 +210,36 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
|
|
|
213
210
|
})
|
|
214
211
|
|
|
215
212
|
client.on('end', function () {
|
|
216
|
-
t.match(chunks, new RegExp(`hello from ${hookOrHandler}`, 'i'))
|
|
217
|
-
|
|
213
|
+
t.assert.match(chunks, new RegExp(`hello from ${hookOrHandler}`, 'i'))
|
|
214
|
+
testDone()
|
|
218
215
|
})
|
|
219
216
|
})
|
|
220
217
|
})
|
|
221
218
|
})
|
|
222
219
|
|
|
223
|
-
test('Throwing an error does not trigger any hooks', t => {
|
|
220
|
+
test('Throwing an error does not trigger any hooks', async (t) => {
|
|
224
221
|
const stream = split(JSON.parse)
|
|
225
222
|
const app = Fastify({
|
|
226
223
|
logger: {
|
|
227
224
|
stream
|
|
228
225
|
}
|
|
229
226
|
})
|
|
230
|
-
t.
|
|
227
|
+
t.after(() => app.close())
|
|
231
228
|
|
|
232
229
|
let errorSeen = false
|
|
233
230
|
stream.on('data', (line) => {
|
|
234
231
|
if (hookOrHandler === 'handler') {
|
|
235
232
|
if (line.level === 40) {
|
|
236
233
|
errorSeen = true
|
|
237
|
-
t.
|
|
234
|
+
t.assert.strictEqual(line.err.code, 'FST_ERR_REP_ALREADY_SENT')
|
|
238
235
|
}
|
|
239
236
|
} else {
|
|
240
|
-
t.
|
|
241
|
-
t.
|
|
237
|
+
t.assert.notStrictEqual(line.level, 40) // there are no errors
|
|
238
|
+
t.assert.notStrictEqual(line.level, 50) // there are no errors
|
|
242
239
|
}
|
|
243
240
|
})
|
|
244
241
|
|
|
245
|
-
previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.
|
|
242
|
+
previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.ok(`${h} should be called`)))
|
|
246
243
|
|
|
247
244
|
if (hookOrHandler === 'handler') {
|
|
248
245
|
app.get('/', (req, reply) => {
|
|
@@ -254,23 +251,22 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
|
|
|
254
251
|
reply.hijack()
|
|
255
252
|
throw new Error('This wil be skipped')
|
|
256
253
|
})
|
|
257
|
-
app.get('/', (req, reply) => t.fail('Handler should not be called'))
|
|
254
|
+
app.get('/', (req, reply) => t.assert.fail('Handler should not be called'))
|
|
258
255
|
}
|
|
259
256
|
|
|
260
|
-
nextHooks.forEach(h => app.addHook(h, async (req, reply) => t.fail(`${h} should not be called`)))
|
|
257
|
+
nextHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.fail(`${h} should not be called`)))
|
|
261
258
|
|
|
262
|
-
|
|
259
|
+
await Promise.race([
|
|
263
260
|
app.inject({ method: 'GET', url: '/' }),
|
|
264
261
|
new Promise((resolve, reject) => setTimeout(resolve, 1000))
|
|
265
|
-
])
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
})
|
|
262
|
+
])
|
|
263
|
+
|
|
264
|
+
if (hookOrHandler === 'handler') {
|
|
265
|
+
t.assert.strictEqual(errorSeen, true)
|
|
266
|
+
}
|
|
271
267
|
})
|
|
272
268
|
|
|
273
|
-
test('Calling reply.send() after hijacking logs a warning', t => {
|
|
269
|
+
test('Calling reply.send() after hijacking logs a warning', async (t) => {
|
|
274
270
|
const stream = split(JSON.parse)
|
|
275
271
|
const app = Fastify({
|
|
276
272
|
logger: {
|
|
@@ -283,11 +279,11 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
|
|
|
283
279
|
stream.on('data', (line) => {
|
|
284
280
|
if (line.level === 40) {
|
|
285
281
|
errorSeen = true
|
|
286
|
-
t.
|
|
282
|
+
t.assert.strictEqual(line.err.code, 'FST_ERR_REP_ALREADY_SENT')
|
|
287
283
|
}
|
|
288
284
|
})
|
|
289
285
|
|
|
290
|
-
previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.
|
|
286
|
+
previousHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.ok(`${h} should be called`)))
|
|
291
287
|
|
|
292
288
|
if (hookOrHandler === 'handler') {
|
|
293
289
|
app.get('/', (req, reply) => {
|
|
@@ -299,18 +295,17 @@ function testHandlerOrBeforeHandlerHook (test, hookOrHandler) {
|
|
|
299
295
|
reply.hijack()
|
|
300
296
|
return reply.send('hello from reply.send()')
|
|
301
297
|
})
|
|
302
|
-
app.get('/', (req, reply) => t.fail('Handler should not be called'))
|
|
298
|
+
app.get('/', (req, reply) => t.assert.fail('Handler should not be called'))
|
|
303
299
|
}
|
|
304
300
|
|
|
305
|
-
nextHooks.forEach(h => app.addHook(h, async (req, reply) => t.fail(`${h} should not be called`)))
|
|
301
|
+
nextHooks.forEach(h => app.addHook(h, async (req, reply) => t.assert.fail(`${h} should not be called`)))
|
|
306
302
|
|
|
307
|
-
|
|
303
|
+
await Promise.race([
|
|
308
304
|
app.inject({ method: 'GET', url: '/' }),
|
|
309
305
|
new Promise((resolve, reject) => setTimeout(resolve, 1000))
|
|
310
|
-
])
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
})
|
|
306
|
+
])
|
|
307
|
+
|
|
308
|
+
t.assert.strictEqual(errorSeen, true)
|
|
314
309
|
})
|
|
315
310
|
})
|
|
316
311
|
}
|
package/test/stream.1.test.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const test = t.test
|
|
3
|
+
const { test } = require('node:test')
|
|
5
4
|
const sget = require('simple-get').concat
|
|
6
5
|
const fs = require('node:fs')
|
|
7
6
|
const Fastify = require('../fastify')
|
|
8
7
|
|
|
9
|
-
test('should respond with a stream', t => {
|
|
8
|
+
test('should respond with a stream', (t, testDone) => {
|
|
10
9
|
t.plan(6)
|
|
11
10
|
const fastify = Fastify()
|
|
12
11
|
|
|
@@ -16,23 +15,24 @@ test('should respond with a stream', t => {
|
|
|
16
15
|
})
|
|
17
16
|
|
|
18
17
|
fastify.listen({ port: 0 }, err => {
|
|
19
|
-
t.
|
|
20
|
-
t.
|
|
18
|
+
t.assert.ifError(err)
|
|
19
|
+
t.after(() => { fastify.close() })
|
|
21
20
|
|
|
22
21
|
sget(`http://localhost:${fastify.server.address().port}`, function (err, response, data) {
|
|
23
|
-
t.
|
|
24
|
-
t.
|
|
25
|
-
t.
|
|
22
|
+
t.assert.ifError(err)
|
|
23
|
+
t.assert.strictEqual(response.headers['content-type'], undefined)
|
|
24
|
+
t.assert.strictEqual(response.statusCode, 200)
|
|
26
25
|
|
|
27
26
|
fs.readFile(__filename, (err, expected) => {
|
|
28
|
-
t.
|
|
29
|
-
t.
|
|
27
|
+
t.assert.ifError(err)
|
|
28
|
+
t.assert.strictEqual(expected.toString(), data.toString())
|
|
29
|
+
testDone()
|
|
30
30
|
})
|
|
31
31
|
})
|
|
32
32
|
})
|
|
33
33
|
})
|
|
34
34
|
|
|
35
|
-
test('should respond with a stream (error)', t => {
|
|
35
|
+
test('should respond with a stream (error)', (t, testDone) => {
|
|
36
36
|
t.plan(3)
|
|
37
37
|
const fastify = Fastify()
|
|
38
38
|
|
|
@@ -42,17 +42,18 @@ test('should respond with a stream (error)', t => {
|
|
|
42
42
|
})
|
|
43
43
|
|
|
44
44
|
fastify.listen({ port: 0 }, err => {
|
|
45
|
-
t.
|
|
46
|
-
t.
|
|
45
|
+
t.assert.ifError(err)
|
|
46
|
+
t.after(() => { fastify.close() })
|
|
47
47
|
|
|
48
48
|
sget(`http://localhost:${fastify.server.address().port}/error`, function (err, response) {
|
|
49
|
-
t.
|
|
50
|
-
t.
|
|
49
|
+
t.assert.ifError(err)
|
|
50
|
+
t.assert.strictEqual(response.statusCode, 500)
|
|
51
|
+
testDone()
|
|
51
52
|
})
|
|
52
53
|
})
|
|
53
54
|
})
|
|
54
55
|
|
|
55
|
-
test('should trigger the onSend hook', t => {
|
|
56
|
+
test('should trigger the onSend hook', (t, testDone) => {
|
|
56
57
|
t.plan(4)
|
|
57
58
|
const fastify = Fastify()
|
|
58
59
|
|
|
@@ -61,7 +62,7 @@ test('should trigger the onSend hook', t => {
|
|
|
61
62
|
})
|
|
62
63
|
|
|
63
64
|
fastify.addHook('onSend', (req, reply, payload, done) => {
|
|
64
|
-
t.ok(payload._readableState)
|
|
65
|
+
t.assert.ok(payload._readableState)
|
|
65
66
|
reply.header('Content-Type', 'application/javascript')
|
|
66
67
|
done()
|
|
67
68
|
})
|
|
@@ -69,14 +70,15 @@ test('should trigger the onSend hook', t => {
|
|
|
69
70
|
fastify.inject({
|
|
70
71
|
url: '/'
|
|
71
72
|
}, (err, res) => {
|
|
72
|
-
t.
|
|
73
|
-
t.
|
|
74
|
-
t.
|
|
73
|
+
t.assert.ifError(err)
|
|
74
|
+
t.assert.strictEqual(res.headers['content-type'], 'application/javascript')
|
|
75
|
+
t.assert.strictEqual(res.payload, fs.readFileSync(__filename, 'utf8'))
|
|
75
76
|
fastify.close()
|
|
77
|
+
testDone()
|
|
76
78
|
})
|
|
77
79
|
})
|
|
78
80
|
|
|
79
|
-
test('should trigger the onSend hook only twice if pumping the stream fails, first with the stream, second with the serialized error', t => {
|
|
81
|
+
test('should trigger the onSend hook only twice if pumping the stream fails, first with the stream, second with the serialized error', (t, testDone) => {
|
|
80
82
|
t.plan(5)
|
|
81
83
|
const fastify = Fastify()
|
|
82
84
|
|
|
@@ -87,22 +89,23 @@ test('should trigger the onSend hook only twice if pumping the stream fails, fir
|
|
|
87
89
|
let counter = 0
|
|
88
90
|
fastify.addHook('onSend', (req, reply, payload, done) => {
|
|
89
91
|
if (counter === 0) {
|
|
90
|
-
t.ok(payload._readableState)
|
|
92
|
+
t.assert.ok(payload._readableState)
|
|
91
93
|
} else if (counter === 1) {
|
|
92
94
|
const error = JSON.parse(payload)
|
|
93
|
-
t.
|
|
95
|
+
t.assert.strictEqual(error.statusCode, 500)
|
|
94
96
|
}
|
|
95
97
|
counter++
|
|
96
98
|
done()
|
|
97
99
|
})
|
|
98
100
|
|
|
99
101
|
fastify.listen({ port: 0 }, err => {
|
|
100
|
-
t.
|
|
101
|
-
t.
|
|
102
|
+
t.assert.ifError(err)
|
|
103
|
+
t.after(() => { fastify.close() })
|
|
102
104
|
|
|
103
105
|
sget(`http://localhost:${fastify.server.address().port}`, function (err, response) {
|
|
104
|
-
t.
|
|
105
|
-
t.
|
|
106
|
+
t.assert.ifError(err)
|
|
107
|
+
t.assert.strictEqual(response.statusCode, 500)
|
|
108
|
+
testDone()
|
|
106
109
|
})
|
|
107
110
|
})
|
|
108
111
|
})
|
package/test/stream.2.test.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const test = t.test
|
|
3
|
+
const { test } = require('node:test')
|
|
5
4
|
const proxyquire = require('proxyquire')
|
|
6
5
|
const fs = require('node:fs')
|
|
7
6
|
const resolve = require('node:path').resolve
|
|
8
7
|
const zlib = require('node:zlib')
|
|
9
8
|
const pipeline = require('node:stream').pipeline
|
|
10
9
|
const Fastify = require('..')
|
|
10
|
+
const { waitForCb } = require('./toolkit')
|
|
11
11
|
|
|
12
12
|
test('onSend hook stream', t => {
|
|
13
13
|
t.plan(4)
|
|
@@ -17,6 +17,8 @@ test('onSend hook stream', t => {
|
|
|
17
17
|
reply.send({ hello: 'world' })
|
|
18
18
|
})
|
|
19
19
|
|
|
20
|
+
const { stepIn, patience } = waitForCb({ steps: 2 })
|
|
21
|
+
|
|
20
22
|
fastify.addHook('onSend', (req, reply, payload, done) => {
|
|
21
23
|
const gzStream = zlib.createGzip()
|
|
22
24
|
|
|
@@ -24,7 +26,10 @@ test('onSend hook stream', t => {
|
|
|
24
26
|
pipeline(
|
|
25
27
|
fs.createReadStream(resolve(__filename), 'utf8'),
|
|
26
28
|
gzStream,
|
|
27
|
-
|
|
29
|
+
(err) => {
|
|
30
|
+
t.assert.ifError(err)
|
|
31
|
+
stepIn()
|
|
32
|
+
}
|
|
28
33
|
)
|
|
29
34
|
done(null, gzStream)
|
|
30
35
|
})
|
|
@@ -33,16 +38,19 @@ test('onSend hook stream', t => {
|
|
|
33
38
|
url: '/',
|
|
34
39
|
method: 'GET'
|
|
35
40
|
}, (err, res) => {
|
|
36
|
-
t.
|
|
37
|
-
t.
|
|
41
|
+
t.assert.ifError(err)
|
|
42
|
+
t.assert.strictEqual(res.headers['content-encoding'], 'gzip')
|
|
38
43
|
const file = fs.readFileSync(resolve(__filename), 'utf8')
|
|
39
44
|
const payload = zlib.gunzipSync(res.rawPayload)
|
|
40
|
-
t.
|
|
45
|
+
t.assert.strictEqual(payload.toString('utf-8'), file)
|
|
41
46
|
fastify.close()
|
|
47
|
+
stepIn()
|
|
42
48
|
})
|
|
49
|
+
|
|
50
|
+
return patience
|
|
43
51
|
})
|
|
44
52
|
|
|
45
|
-
test('onSend hook stream should work even if payload is not a proper stream', t => {
|
|
53
|
+
test('onSend hook stream should work even if payload is not a proper stream', (t, testDone) => {
|
|
46
54
|
t.plan(1)
|
|
47
55
|
|
|
48
56
|
const reply = proxyquire('../lib/reply', {
|
|
@@ -59,8 +67,9 @@ test('onSend hook stream should work even if payload is not a proper stream', t
|
|
|
59
67
|
fatal: () => { },
|
|
60
68
|
error: () => { },
|
|
61
69
|
warn: (message) => {
|
|
62
|
-
t.
|
|
70
|
+
t.assert.strictEqual(message, 'stream payload does not end properly')
|
|
63
71
|
fastify.close()
|
|
72
|
+
testDone()
|
|
64
73
|
},
|
|
65
74
|
info: () => { },
|
|
66
75
|
debug: () => { },
|
|
@@ -83,7 +92,7 @@ test('onSend hook stream should work even if payload is not a proper stream', t
|
|
|
83
92
|
})
|
|
84
93
|
})
|
|
85
94
|
|
|
86
|
-
test('onSend hook stream should work on payload with "close" ending function', t => {
|
|
95
|
+
test('onSend hook stream should work on payload with "close" ending function', (t, testDone) => {
|
|
87
96
|
t.plan(1)
|
|
88
97
|
|
|
89
98
|
const reply = proxyquire('../lib/reply', {
|
|
@@ -106,7 +115,8 @@ test('onSend hook stream should work on payload with "close" ending function', t
|
|
|
106
115
|
pipe: () => { },
|
|
107
116
|
close: (cb) => {
|
|
108
117
|
cb()
|
|
109
|
-
t.
|
|
118
|
+
t.assert.ok('close callback called')
|
|
119
|
+
testDone()
|
|
110
120
|
}
|
|
111
121
|
}
|
|
112
122
|
done(null, fakeStream)
|