fastify 3.26.0 → 4.0.0-alpha.1
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 +5 -4
- package/build/build-error-serializer.js +27 -0
- package/build/build-validation.js +49 -35
- package/docs/Guides/Ecosystem.md +2 -1
- package/docs/Guides/Prototype-Poisoning.md +3 -3
- package/docs/Migration-Guide-V4.md +12 -0
- package/docs/Reference/ContentTypeParser.md +8 -1
- package/docs/Reference/Errors.md +51 -6
- package/docs/Reference/Hooks.md +4 -7
- package/docs/Reference/LTS.md +5 -4
- package/docs/Reference/Reply.md +23 -22
- package/docs/Reference/Request.md +1 -3
- package/docs/Reference/Routes.md +17 -10
- package/docs/Reference/Server.md +98 -63
- package/docs/Reference/TypeScript.md +11 -13
- package/docs/Reference/Validation-and-Serialization.md +32 -54
- package/docs/Type-Providers.md +257 -0
- package/examples/hooks.js +1 -1
- package/examples/simple-stream.js +18 -0
- package/fastify.d.ts +36 -22
- package/fastify.js +72 -53
- package/lib/configValidator.js +902 -1023
- package/lib/contentTypeParser.js +6 -16
- package/lib/context.js +36 -10
- package/lib/decorate.js +5 -3
- package/lib/error-handler.js +158 -0
- package/lib/error-serializer.js +257 -0
- package/lib/errors.js +49 -10
- package/lib/fourOhFour.js +31 -20
- package/lib/handleRequest.js +10 -13
- package/lib/hooks.js +14 -9
- package/lib/noop-set.js +10 -0
- package/lib/pluginOverride.js +0 -3
- package/lib/pluginUtils.js +3 -2
- package/lib/reply.js +44 -163
- package/lib/request.js +13 -10
- package/lib/route.js +158 -139
- package/lib/schema-controller.js +3 -3
- package/lib/schemas.js +27 -1
- package/lib/server.js +219 -116
- package/lib/symbols.js +6 -4
- package/lib/validation.js +2 -1
- package/lib/warnings.js +2 -12
- package/lib/wrapThenable.js +4 -11
- package/package.json +40 -45
- package/test/404s.test.js +265 -108
- package/test/500s.test.js +2 -2
- package/test/async-await.test.js +15 -71
- package/test/close.test.js +39 -1
- package/test/content-parser.test.js +32 -0
- package/test/context-config.test.js +56 -4
- package/test/custom-http-server.test.js +14 -7
- package/test/custom-parser-async.test.js +0 -65
- package/test/custom-parser.test.js +54 -121
- package/test/decorator.test.js +1 -3
- package/test/delete.test.js +5 -5
- package/test/encapsulated-error-handler.test.js +50 -0
- package/test/esm/index.test.js +0 -14
- package/test/fastify-instance.test.js +4 -4
- package/test/fluent-schema.test.js +4 -4
- package/test/get.test.js +3 -3
- package/test/helper.js +18 -3
- package/test/hooks-async.test.js +14 -47
- package/test/hooks.on-ready.test.js +9 -4
- package/test/hooks.test.js +58 -99
- package/test/http2/closing.test.js +5 -11
- package/test/http2/unknown-http-method.test.js +3 -9
- package/test/https/custom-https-server.test.js +12 -6
- package/test/inject.test.js +1 -1
- package/test/input-validation.js +2 -2
- package/test/internals/all.test.js +2 -2
- package/test/internals/contentTypeParser.test.js +4 -4
- package/test/internals/handleRequest.test.js +9 -46
- package/test/internals/initialConfig.test.js +33 -12
- package/test/internals/logger.test.js +1 -1
- package/test/internals/reply.test.js +245 -3
- package/test/internals/request.test.js +13 -7
- package/test/internals/server.test.js +88 -0
- package/test/listen.test.js +84 -1
- package/test/logger.test.js +98 -58
- package/test/maxRequestsPerSocket.test.js +8 -6
- package/test/middleware.test.js +2 -25
- package/test/noop-set.test.js +19 -0
- package/test/nullable-validation.test.js +51 -14
- package/test/plugin.test.js +31 -5
- package/test/pretty-print.test.js +22 -10
- package/test/reply-error.test.js +123 -12
- package/test/request-error.test.js +2 -5
- package/test/route-hooks.test.js +17 -17
- package/test/route-prefix.test.js +2 -1
- package/test/route.test.js +216 -20
- package/test/router-options.test.js +1 -1
- package/test/schema-examples.test.js +11 -5
- package/test/schema-feature.test.js +24 -19
- package/test/schema-serialization.test.js +50 -9
- package/test/schema-special-usage.test.js +14 -81
- package/test/schema-validation.test.js +9 -9
- package/test/skip-reply-send.test.js +8 -8
- package/test/stream.test.js +23 -12
- package/test/throw.test.js +8 -5
- package/test/trust-proxy.test.js +1 -1
- package/test/type-provider.test.js +20 -0
- package/test/types/fastify.test-d.ts +12 -18
- package/test/types/hooks.test-d.ts +7 -3
- package/test/types/import.js +2 -0
- package/test/types/import.ts +1 -0
- package/test/types/instance.test-d.ts +61 -15
- package/test/types/logger.test-d.ts +44 -15
- package/test/types/route.test-d.ts +8 -2
- package/test/types/schema.test-d.ts +2 -39
- package/test/types/type-provider.test-d.ts +417 -0
- package/test/validation-error-handling.test.js +9 -9
- package/test/versioned-routes.test.js +29 -17
- package/test/wrapThenable.test.js +7 -6
- package/types/.eslintrc.json +1 -1
- package/types/content-type-parser.d.ts +17 -8
- package/types/hooks.d.ts +107 -60
- package/types/instance.d.ts +137 -105
- package/types/logger.d.ts +18 -104
- package/types/plugin.d.ts +10 -4
- package/types/register.d.ts +1 -1
- package/types/reply.d.ts +16 -11
- package/types/request.d.ts +10 -5
- package/types/route.d.ts +42 -31
- package/types/schema.d.ts +15 -1
- package/types/type-provider.d.ts +99 -0
- package/types/utils.d.ts +1 -1
- package/lib/schema-compilers.js +0 -12
- package/test/emit-warning.test.js +0 -166
package/test/logger.test.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { test, teardown } = require('tap')
|
|
3
|
+
const { test, teardown, before } = require('tap')
|
|
4
|
+
const helper = require('./helper')
|
|
4
5
|
const http = require('http')
|
|
5
6
|
const stream = require('stream')
|
|
6
7
|
const split = require('split2')
|
|
@@ -10,9 +11,12 @@ const path = require('path')
|
|
|
10
11
|
const os = require('os')
|
|
11
12
|
const fs = require('fs')
|
|
12
13
|
const sget = require('simple-get').concat
|
|
14
|
+
const dns = require('dns')
|
|
13
15
|
|
|
14
16
|
const files = []
|
|
15
17
|
let count = 0
|
|
18
|
+
let localhost
|
|
19
|
+
let localhostForURL
|
|
16
20
|
|
|
17
21
|
function file () {
|
|
18
22
|
const file = path.join(os.tmpdir(), `sonic-boom-${process.pid}-${process.hrtime().toString()}-${count++}`)
|
|
@@ -20,6 +24,10 @@ function file () {
|
|
|
20
24
|
return file
|
|
21
25
|
}
|
|
22
26
|
|
|
27
|
+
before(async function () {
|
|
28
|
+
[localhost, localhostForURL] = await helper.getLoopbackHost()
|
|
29
|
+
})
|
|
30
|
+
|
|
23
31
|
teardown(() => {
|
|
24
32
|
files.forEach((file) => {
|
|
25
33
|
try {
|
|
@@ -31,13 +39,12 @@ teardown(() => {
|
|
|
31
39
|
})
|
|
32
40
|
|
|
33
41
|
test('defaults to info level', t => {
|
|
34
|
-
t.plan(13)
|
|
35
42
|
let fastify = null
|
|
36
43
|
const stream = split(JSON.parse)
|
|
37
44
|
try {
|
|
38
45
|
fastify = Fastify({
|
|
39
46
|
logger: {
|
|
40
|
-
stream
|
|
47
|
+
stream
|
|
41
48
|
}
|
|
42
49
|
})
|
|
43
50
|
} catch (e) {
|
|
@@ -49,9 +56,28 @@ test('defaults to info level', t => {
|
|
|
49
56
|
reply.send({ hello: 'world' })
|
|
50
57
|
})
|
|
51
58
|
|
|
52
|
-
|
|
53
|
-
t.
|
|
59
|
+
fastify.listen(0, err => {
|
|
60
|
+
t.error(err)
|
|
61
|
+
fastify.server.unref()
|
|
62
|
+
|
|
63
|
+
dns.lookup('localhost', { all: true }, function (err, addresses) {
|
|
64
|
+
t.error(err)
|
|
65
|
+
let toSkip = addresses.length
|
|
66
|
+
|
|
67
|
+
function skip (data) {
|
|
68
|
+
if (--toSkip === 0) {
|
|
69
|
+
stream.removeListener('data', skip)
|
|
70
|
+
check()
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
stream.on('data', skip)
|
|
54
75
|
|
|
76
|
+
http.get(`http://${localhostForURL}:` + fastify.server.address().port)
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
function check () {
|
|
55
81
|
stream.once('data', line => {
|
|
56
82
|
const id = line.reqId
|
|
57
83
|
t.ok(line.reqId, 'reqId is defined')
|
|
@@ -66,16 +92,10 @@ test('defaults to info level', t => {
|
|
|
66
92
|
t.equal(line.msg, 'request completed', 'message is set')
|
|
67
93
|
t.equal(line.res.statusCode, 200, 'statusCode is 200')
|
|
68
94
|
t.ok(line.responseTime, 'responseTime is defined')
|
|
95
|
+
t.end()
|
|
69
96
|
})
|
|
70
97
|
})
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
fastify.listen(0, err => {
|
|
74
|
-
t.error(err)
|
|
75
|
-
fastify.server.unref()
|
|
76
|
-
|
|
77
|
-
http.get('http://localhost:' + fastify.server.address().port)
|
|
78
|
-
})
|
|
98
|
+
}
|
|
79
99
|
})
|
|
80
100
|
|
|
81
101
|
test('test log stream', t => {
|
|
@@ -85,7 +105,7 @@ test('test log stream', t => {
|
|
|
85
105
|
try {
|
|
86
106
|
fastify = Fastify({
|
|
87
107
|
logger: {
|
|
88
|
-
stream
|
|
108
|
+
stream,
|
|
89
109
|
level: 'info'
|
|
90
110
|
}
|
|
91
111
|
})
|
|
@@ -98,11 +118,11 @@ test('test log stream', t => {
|
|
|
98
118
|
reply.send({ hello: 'world' })
|
|
99
119
|
})
|
|
100
120
|
|
|
101
|
-
fastify.listen(0, err => {
|
|
121
|
+
fastify.listen(0, localhost, err => {
|
|
102
122
|
t.error(err)
|
|
103
123
|
fastify.server.unref()
|
|
104
124
|
|
|
105
|
-
http.get(
|
|
125
|
+
http.get(`http://${localhostForURL}:` + fastify.server.address().port)
|
|
106
126
|
stream.once('data', listenAtLogLine => {
|
|
107
127
|
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
108
128
|
|
|
@@ -132,7 +152,7 @@ test('test error log stream', t => {
|
|
|
132
152
|
try {
|
|
133
153
|
fastify = Fastify({
|
|
134
154
|
logger: {
|
|
135
|
-
stream
|
|
155
|
+
stream,
|
|
136
156
|
level: 'info'
|
|
137
157
|
}
|
|
138
158
|
})
|
|
@@ -145,11 +165,11 @@ test('test error log stream', t => {
|
|
|
145
165
|
reply.send(new Error('kaboom'))
|
|
146
166
|
})
|
|
147
167
|
|
|
148
|
-
fastify.listen(0, err => {
|
|
168
|
+
fastify.listen(0, localhost, err => {
|
|
149
169
|
t.error(err)
|
|
150
170
|
fastify.server.unref()
|
|
151
171
|
|
|
152
|
-
http.get(
|
|
172
|
+
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
153
173
|
stream.once('data', listenAtLogLine => {
|
|
154
174
|
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
155
175
|
|
|
@@ -182,7 +202,7 @@ test('can use external logger instance', t => {
|
|
|
182
202
|
|
|
183
203
|
const logger = require('pino')(splitStream)
|
|
184
204
|
|
|
185
|
-
const localFastify = Fastify({ logger
|
|
205
|
+
const localFastify = Fastify({ logger })
|
|
186
206
|
|
|
187
207
|
localFastify.get('/foo', function (req, reply) {
|
|
188
208
|
t.ok(req.log)
|
|
@@ -190,9 +210,9 @@ test('can use external logger instance', t => {
|
|
|
190
210
|
reply.send({ hello: 'world' })
|
|
191
211
|
})
|
|
192
212
|
|
|
193
|
-
localFastify.listen(0, err => {
|
|
213
|
+
localFastify.listen(0, localhost, err => {
|
|
194
214
|
t.error(err)
|
|
195
|
-
http.get(
|
|
215
|
+
http.get(`http://${localhostForURL}:` + localFastify.server.address().port + '/foo', (res) => {
|
|
196
216
|
res.resume()
|
|
197
217
|
res.on('end', () => {
|
|
198
218
|
localFastify.server.close()
|
|
@@ -226,7 +246,7 @@ test('can use external logger instance with custom serializer', t => {
|
|
|
226
246
|
}, splitStream)
|
|
227
247
|
|
|
228
248
|
const localFastify = Fastify({
|
|
229
|
-
logger
|
|
249
|
+
logger
|
|
230
250
|
})
|
|
231
251
|
|
|
232
252
|
localFastify.get('/foo', function (req, reply) {
|
|
@@ -235,9 +255,9 @@ test('can use external logger instance with custom serializer', t => {
|
|
|
235
255
|
reply.send({ hello: 'world' })
|
|
236
256
|
})
|
|
237
257
|
|
|
238
|
-
localFastify.listen(0, err => {
|
|
258
|
+
localFastify.listen(0, localhost, err => {
|
|
239
259
|
t.error(err)
|
|
240
|
-
http.get(
|
|
260
|
+
http.get(`http://${localhostForURL}:` + localFastify.server.address().port + '/foo', (res) => {
|
|
241
261
|
res.resume()
|
|
242
262
|
res.on('end', () => {
|
|
243
263
|
localFastify.server.close()
|
|
@@ -253,7 +273,7 @@ test('expose the logger', t => {
|
|
|
253
273
|
try {
|
|
254
274
|
fastify = Fastify({
|
|
255
275
|
logger: {
|
|
256
|
-
stream
|
|
276
|
+
stream,
|
|
257
277
|
level: 'info'
|
|
258
278
|
}
|
|
259
279
|
})
|
|
@@ -271,7 +291,7 @@ test('The request id header key can be customized', t => {
|
|
|
271
291
|
|
|
272
292
|
const stream = split(JSON.parse)
|
|
273
293
|
const fastify = Fastify({
|
|
274
|
-
logger: { stream
|
|
294
|
+
logger: { stream, level: 'info' },
|
|
275
295
|
requestIdHeader: 'my-custom-request-id'
|
|
276
296
|
})
|
|
277
297
|
t.teardown(() => fastify.close())
|
|
@@ -316,7 +336,7 @@ test('The request id header key can be customized along with a custom id generat
|
|
|
316
336
|
|
|
317
337
|
const stream = split(JSON.parse)
|
|
318
338
|
const fastify = Fastify({
|
|
319
|
-
logger: { stream
|
|
339
|
+
logger: { stream, level: 'info' },
|
|
320
340
|
requestIdHeader: 'my-custom-request-id',
|
|
321
341
|
genReqId (req) {
|
|
322
342
|
return 'foo'
|
|
@@ -379,7 +399,7 @@ test('The request id log label can be changed', t => {
|
|
|
379
399
|
|
|
380
400
|
const stream = split(JSON.parse)
|
|
381
401
|
const fastify = Fastify({
|
|
382
|
-
logger: { stream
|
|
402
|
+
logger: { stream, level: 'info' },
|
|
383
403
|
requestIdHeader: 'my-custom-request-id',
|
|
384
404
|
requestIdLogLabel: 'traceId'
|
|
385
405
|
})
|
|
@@ -422,7 +442,7 @@ test('The logger should accept custom serializer', t => {
|
|
|
422
442
|
const stream = split(JSON.parse)
|
|
423
443
|
const fastify = Fastify({
|
|
424
444
|
logger: {
|
|
425
|
-
stream
|
|
445
|
+
stream,
|
|
426
446
|
level: 'info',
|
|
427
447
|
serializers: {
|
|
428
448
|
req: function (req) {
|
|
@@ -439,11 +459,11 @@ test('The logger should accept custom serializer', t => {
|
|
|
439
459
|
reply.send(new Error('kaboom'))
|
|
440
460
|
})
|
|
441
461
|
|
|
442
|
-
fastify.listen(0, err => {
|
|
462
|
+
fastify.listen(0, localhost, err => {
|
|
443
463
|
t.error(err)
|
|
444
464
|
fastify.server.unref()
|
|
445
465
|
|
|
446
|
-
http.get(
|
|
466
|
+
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/custom')
|
|
447
467
|
stream.once('data', listenAtLogLine => {
|
|
448
468
|
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
449
469
|
|
|
@@ -1151,7 +1171,7 @@ test('should serialize request and response', t => {
|
|
|
1151
1171
|
const stream = split(JSON.parse)
|
|
1152
1172
|
const fastify = Fastify({
|
|
1153
1173
|
logger: {
|
|
1154
|
-
stream
|
|
1174
|
+
stream,
|
|
1155
1175
|
level: 'info'
|
|
1156
1176
|
}
|
|
1157
1177
|
})
|
|
@@ -1173,7 +1193,7 @@ test('Do not wrap IPv4 address', t => {
|
|
|
1173
1193
|
const stream = split(JSON.parse)
|
|
1174
1194
|
const fastify = Fastify({
|
|
1175
1195
|
logger: {
|
|
1176
|
-
stream
|
|
1196
|
+
stream,
|
|
1177
1197
|
level: 'info'
|
|
1178
1198
|
}
|
|
1179
1199
|
})
|
|
@@ -1204,11 +1224,11 @@ test('file option', t => {
|
|
|
1204
1224
|
reply.send({ hello: 'world' })
|
|
1205
1225
|
})
|
|
1206
1226
|
|
|
1207
|
-
fastify.listen(0, err => {
|
|
1227
|
+
fastify.listen(0, localhost, err => {
|
|
1208
1228
|
t.error(err)
|
|
1209
1229
|
fastify.server.unref()
|
|
1210
1230
|
|
|
1211
|
-
http.get(
|
|
1231
|
+
http.get(`http://${localhostForURL}:` + fastify.server.address().port, () => {
|
|
1212
1232
|
const stream = fs.createReadStream(dest).pipe(split(JSON.parse))
|
|
1213
1233
|
|
|
1214
1234
|
stream.once('data', listenAtLogLine => {
|
|
@@ -1241,7 +1261,7 @@ test('should log the error if no error handler is defined', t => {
|
|
|
1241
1261
|
const stream = split(JSON.parse)
|
|
1242
1262
|
const fastify = Fastify({
|
|
1243
1263
|
logger: {
|
|
1244
|
-
stream
|
|
1264
|
+
stream,
|
|
1245
1265
|
level: 'info'
|
|
1246
1266
|
}
|
|
1247
1267
|
})
|
|
@@ -1249,10 +1269,10 @@ test('should log the error if no error handler is defined', t => {
|
|
|
1249
1269
|
t.ok(req.log)
|
|
1250
1270
|
reply.send(new Error('a generic error'))
|
|
1251
1271
|
})
|
|
1252
|
-
fastify.listen(0, err => {
|
|
1272
|
+
fastify.listen(0, localhost, err => {
|
|
1253
1273
|
t.error(err)
|
|
1254
1274
|
fastify.server.unref()
|
|
1255
|
-
http.get(
|
|
1275
|
+
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
1256
1276
|
stream.once('data', listenAtLogLine => {
|
|
1257
1277
|
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
1258
1278
|
stream.once('data', line => {
|
|
@@ -1275,7 +1295,7 @@ test('should log as info if error status code >= 400 and < 500 if no error handl
|
|
|
1275
1295
|
const stream = split(JSON.parse)
|
|
1276
1296
|
const fastify = Fastify({
|
|
1277
1297
|
logger: {
|
|
1278
|
-
stream
|
|
1298
|
+
stream,
|
|
1279
1299
|
level: 'info'
|
|
1280
1300
|
}
|
|
1281
1301
|
})
|
|
@@ -1287,10 +1307,10 @@ test('should log as info if error status code >= 400 and < 500 if no error handl
|
|
|
1287
1307
|
t.ok(req.log)
|
|
1288
1308
|
reply.send(Object.assign(new Error('a 503 error'), { statusCode: 503 }))
|
|
1289
1309
|
})
|
|
1290
|
-
fastify.listen(0, err => {
|
|
1310
|
+
fastify.listen(0, localhost, err => {
|
|
1291
1311
|
t.error(err)
|
|
1292
1312
|
fastify.server.unref()
|
|
1293
|
-
http.get(
|
|
1313
|
+
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/400')
|
|
1294
1314
|
stream.once('data', listenAtLogLine => {
|
|
1295
1315
|
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
1296
1316
|
stream.once('data', line => {
|
|
@@ -1313,7 +1333,7 @@ test('should log as error if error status code >= 500 if no error handler is def
|
|
|
1313
1333
|
const stream = split(JSON.parse)
|
|
1314
1334
|
const fastify = Fastify({
|
|
1315
1335
|
logger: {
|
|
1316
|
-
stream
|
|
1336
|
+
stream,
|
|
1317
1337
|
level: 'info'
|
|
1318
1338
|
}
|
|
1319
1339
|
})
|
|
@@ -1321,10 +1341,10 @@ test('should log as error if error status code >= 500 if no error handler is def
|
|
|
1321
1341
|
t.ok(req.log)
|
|
1322
1342
|
reply.send(Object.assign(new Error('a 503 error'), { statusCode: 503 }))
|
|
1323
1343
|
})
|
|
1324
|
-
fastify.listen(0, err => {
|
|
1344
|
+
fastify.listen(0, localhost, err => {
|
|
1325
1345
|
t.error(err)
|
|
1326
1346
|
fastify.server.unref()
|
|
1327
|
-
http.get(
|
|
1347
|
+
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/503')
|
|
1328
1348
|
stream.once('data', listenAtLogLine => {
|
|
1329
1349
|
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
1330
1350
|
stream.once('data', line => {
|
|
@@ -1342,12 +1362,12 @@ test('should log as error if error status code >= 500 if no error handler is def
|
|
|
1342
1362
|
})
|
|
1343
1363
|
})
|
|
1344
1364
|
|
|
1345
|
-
test('should not log the error if error handler is defined', t => {
|
|
1346
|
-
t.plan(
|
|
1365
|
+
test('should not log the error if error handler is defined and it does not error', t => {
|
|
1366
|
+
t.plan(8)
|
|
1347
1367
|
const stream = split(JSON.parse)
|
|
1348
1368
|
const fastify = Fastify({
|
|
1349
1369
|
logger: {
|
|
1350
|
-
stream
|
|
1370
|
+
stream,
|
|
1351
1371
|
level: 'info'
|
|
1352
1372
|
}
|
|
1353
1373
|
})
|
|
@@ -1356,12 +1376,13 @@ test('should not log the error if error handler is defined', t => {
|
|
|
1356
1376
|
reply.send(new Error('something happened'))
|
|
1357
1377
|
})
|
|
1358
1378
|
fastify.setErrorHandler((err, req, reply) => {
|
|
1359
|
-
|
|
1379
|
+
t.ok(err)
|
|
1380
|
+
reply.send('something bad happened')
|
|
1360
1381
|
})
|
|
1361
|
-
fastify.listen(0, err => {
|
|
1382
|
+
fastify.listen(0, localhost, err => {
|
|
1362
1383
|
t.error(err)
|
|
1363
1384
|
fastify.server.unref()
|
|
1364
|
-
http.get(
|
|
1385
|
+
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
1365
1386
|
stream.once('data', listenAtLogLine => {
|
|
1366
1387
|
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
1367
1388
|
stream.once('data', line => {
|
|
@@ -1369,7 +1390,7 @@ test('should not log the error if error handler is defined', t => {
|
|
|
1369
1390
|
stream.once('data', line => {
|
|
1370
1391
|
t.equal(line.level, 30, 'level is correct')
|
|
1371
1392
|
t.equal(line.msg, 'request completed', 'message is set')
|
|
1372
|
-
t.same(line.res, { statusCode:
|
|
1393
|
+
t.same(line.res, { statusCode: 200 }, 'status code is set')
|
|
1373
1394
|
})
|
|
1374
1395
|
})
|
|
1375
1396
|
})
|
|
@@ -1381,7 +1402,7 @@ test('should not rely on raw request to log errors', t => {
|
|
|
1381
1402
|
const stream = split(JSON.parse)
|
|
1382
1403
|
const fastify = Fastify({
|
|
1383
1404
|
logger: {
|
|
1384
|
-
stream
|
|
1405
|
+
stream,
|
|
1385
1406
|
level: 'info'
|
|
1386
1407
|
}
|
|
1387
1408
|
})
|
|
@@ -1389,10 +1410,10 @@ test('should not rely on raw request to log errors', t => {
|
|
|
1389
1410
|
t.ok(req.log)
|
|
1390
1411
|
reply.status(415).send(new Error('something happened'))
|
|
1391
1412
|
})
|
|
1392
|
-
fastify.listen(0, err => {
|
|
1413
|
+
fastify.listen(0, localhost, err => {
|
|
1393
1414
|
t.error(err)
|
|
1394
1415
|
fastify.server.unref()
|
|
1395
|
-
http.get(
|
|
1416
|
+
http.get(`http://${localhostForURL}:` + fastify.server.address().port + '/error')
|
|
1396
1417
|
stream.once('data', listenAtLogLine => {
|
|
1397
1418
|
t.ok(listenAtLogLine, 'listen at log message is ok')
|
|
1398
1419
|
stream.once('data', line => {
|
|
@@ -1412,7 +1433,7 @@ test('should redact the authorization header if so specified', t => {
|
|
|
1412
1433
|
const stream = split(JSON.parse)
|
|
1413
1434
|
const fastify = Fastify({
|
|
1414
1435
|
logger: {
|
|
1415
|
-
stream
|
|
1436
|
+
stream,
|
|
1416
1437
|
redact: ['req.headers.authorization'],
|
|
1417
1438
|
level: 'info',
|
|
1418
1439
|
serializers: {
|
|
@@ -1439,12 +1460,12 @@ test('should redact the authorization header if so specified', t => {
|
|
|
1439
1460
|
t.equal(line.req.headers.authorization, '[Redacted]', 'authorization is redacted')
|
|
1440
1461
|
})
|
|
1441
1462
|
})
|
|
1442
|
-
fastify.listen(0, err => {
|
|
1463
|
+
fastify.listen(0, localhost, err => {
|
|
1443
1464
|
t.error(err)
|
|
1444
1465
|
fastify.server.unref()
|
|
1445
1466
|
sget({
|
|
1446
1467
|
method: 'GET',
|
|
1447
|
-
url:
|
|
1468
|
+
url: `http://${localhostForURL}:` + fastify.server.address().port,
|
|
1448
1469
|
headers: {
|
|
1449
1470
|
authorization: 'Bearer abcde'
|
|
1450
1471
|
}
|
|
@@ -1481,6 +1502,25 @@ test('should not log incoming request and outgoing response when disabled', t =>
|
|
|
1481
1502
|
})
|
|
1482
1503
|
})
|
|
1483
1504
|
|
|
1505
|
+
test('should not log incoming request and outgoing response for 404 onBadUrl when disabled', t => {
|
|
1506
|
+
t.plan(1)
|
|
1507
|
+
const lines = []
|
|
1508
|
+
const dest = new stream.Writable({
|
|
1509
|
+
write: function (chunk, enc, cb) {
|
|
1510
|
+
lines.push(JSON.parse(chunk))
|
|
1511
|
+
cb()
|
|
1512
|
+
}
|
|
1513
|
+
})
|
|
1514
|
+
const fastify = Fastify({ disableRequestLogging: true, logger: { level: 'info', stream: dest } })
|
|
1515
|
+
|
|
1516
|
+
fastify.inject({
|
|
1517
|
+
url: '/%c0',
|
|
1518
|
+
method: 'GET'
|
|
1519
|
+
}, (e, res) => {
|
|
1520
|
+
t.same(lines.length, 0)
|
|
1521
|
+
})
|
|
1522
|
+
})
|
|
1523
|
+
|
|
1484
1524
|
test('should pass when using unWritable props in the logger option', t => {
|
|
1485
1525
|
t.plan(1)
|
|
1486
1526
|
Fastify({
|
|
@@ -21,12 +21,12 @@ test('maxRequestsPerSocket on node version >= 16.10.0', { skip }, t => {
|
|
|
21
21
|
t.error(err)
|
|
22
22
|
|
|
23
23
|
const port = fastify.server.address().port
|
|
24
|
-
const client = net.createConnection({ port
|
|
24
|
+
const client = net.createConnection({ port }, () => {
|
|
25
25
|
client.write('GET / HTTP/1.1\r\n\r\n')
|
|
26
26
|
|
|
27
27
|
client.once('data', data => {
|
|
28
28
|
t.match(data.toString(), /Connection:\s*keep-alive/i)
|
|
29
|
-
t.match(data.toString(), /Keep-Alive:\s*timeout
|
|
29
|
+
t.match(data.toString(), /Keep-Alive:\s*timeout=\d+/i)
|
|
30
30
|
t.match(data.toString(), /200 OK/i)
|
|
31
31
|
|
|
32
32
|
client.write('GET / HTTP/1.1\r\n\r\n')
|
|
@@ -40,6 +40,7 @@ test('maxRequestsPerSocket on node version >= 16.10.0', { skip }, t => {
|
|
|
40
40
|
client.once('data', data => {
|
|
41
41
|
t.match(data.toString(), /Connection:\s*close/i)
|
|
42
42
|
t.match(data.toString(), /503 Service Unavailable/i)
|
|
43
|
+
client.end()
|
|
43
44
|
})
|
|
44
45
|
})
|
|
45
46
|
})
|
|
@@ -61,27 +62,28 @@ test('maxRequestsPerSocket zero should behave same as null', { skip }, t => {
|
|
|
61
62
|
t.error(err)
|
|
62
63
|
|
|
63
64
|
const port = fastify.server.address().port
|
|
64
|
-
const client = net.createConnection({ port
|
|
65
|
+
const client = net.createConnection({ port }, () => {
|
|
65
66
|
client.write('GET / HTTP/1.1\r\n\r\n')
|
|
66
67
|
|
|
67
68
|
client.once('data', data => {
|
|
68
69
|
t.match(data.toString(), /Connection:\s*keep-alive/i)
|
|
69
|
-
t.match(data.toString(), /Keep-Alive:\s*timeout
|
|
70
|
+
t.match(data.toString(), /Keep-Alive:\s*timeout=\d+/i)
|
|
70
71
|
t.match(data.toString(), /200 OK/i)
|
|
71
72
|
|
|
72
73
|
client.write('GET / HTTP/1.1\r\n\r\n')
|
|
73
74
|
|
|
74
75
|
client.once('data', data => {
|
|
75
76
|
t.match(data.toString(), /Connection:\s*keep-alive/i)
|
|
76
|
-
t.match(data.toString(), /Keep-Alive:\s*timeout
|
|
77
|
+
t.match(data.toString(), /Keep-Alive:\s*timeout=\d+/i)
|
|
77
78
|
t.match(data.toString(), /200 OK/i)
|
|
78
79
|
|
|
79
80
|
client.write('GET / HTTP/1.1\r\n\r\n')
|
|
80
81
|
|
|
81
82
|
client.once('data', data => {
|
|
82
83
|
t.match(data.toString(), /Connection:\s*keep-alive/i)
|
|
83
|
-
t.match(data.toString(), /Keep-Alive:\s*timeout
|
|
84
|
+
t.match(data.toString(), /Keep-Alive:\s*timeout=\d+/i)
|
|
84
85
|
t.match(data.toString(), /200 OK/i)
|
|
86
|
+
client.end()
|
|
85
87
|
})
|
|
86
88
|
})
|
|
87
89
|
})
|
package/test/middleware.test.js
CHANGED
|
@@ -3,22 +3,9 @@
|
|
|
3
3
|
const { test } = require('tap')
|
|
4
4
|
const Fastify = require('..')
|
|
5
5
|
const {
|
|
6
|
-
FST_ERR_DEC_ALREADY_PRESENT
|
|
7
|
-
FST_ERR_MISSING_MIDDLEWARE
|
|
6
|
+
FST_ERR_DEC_ALREADY_PRESENT
|
|
8
7
|
} = require('../lib/errors')
|
|
9
8
|
|
|
10
|
-
test('Should throw if the basic use API has not been overridden', t => {
|
|
11
|
-
t.plan(1)
|
|
12
|
-
const fastify = Fastify()
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
fastify.use()
|
|
16
|
-
t.fail('Should throw')
|
|
17
|
-
} catch (err) {
|
|
18
|
-
t.ok(err instanceof FST_ERR_MISSING_MIDDLEWARE)
|
|
19
|
-
}
|
|
20
|
-
})
|
|
21
|
-
|
|
22
9
|
test('Should be able to override the default use API', t => {
|
|
23
10
|
t.plan(1)
|
|
24
11
|
const fastify = Fastify()
|
|
@@ -38,7 +25,7 @@ test('Cannot decorate use twice', t => {
|
|
|
38
25
|
})
|
|
39
26
|
|
|
40
27
|
test('Encapsulation works', t => {
|
|
41
|
-
t.plan(
|
|
28
|
+
t.plan(1)
|
|
42
29
|
const fastify = Fastify()
|
|
43
30
|
|
|
44
31
|
fastify.register((instance, opts, done) => {
|
|
@@ -47,15 +34,5 @@ test('Encapsulation works', t => {
|
|
|
47
34
|
done()
|
|
48
35
|
})
|
|
49
36
|
|
|
50
|
-
fastify.register((instance, opts, done) => {
|
|
51
|
-
try {
|
|
52
|
-
instance.use()
|
|
53
|
-
t.fail('Should throw')
|
|
54
|
-
} catch (err) {
|
|
55
|
-
t.ok(err instanceof FST_ERR_MISSING_MIDDLEWARE)
|
|
56
|
-
}
|
|
57
|
-
done()
|
|
58
|
-
})
|
|
59
|
-
|
|
60
37
|
fastify.ready()
|
|
61
38
|
})
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const tap = require('tap')
|
|
4
|
+
const noopSet = require('../lib/noop-set')
|
|
5
|
+
|
|
6
|
+
tap.test('does a lot of nothing', async t => {
|
|
7
|
+
const aSet = noopSet()
|
|
8
|
+
t.type(aSet, 'object')
|
|
9
|
+
|
|
10
|
+
const item = {}
|
|
11
|
+
aSet.add(item)
|
|
12
|
+
aSet.add({ another: 'item' })
|
|
13
|
+
aSet.delete(item)
|
|
14
|
+
t.equal(aSet.has(item), true)
|
|
15
|
+
|
|
16
|
+
for (const i of aSet) {
|
|
17
|
+
t.fail('should not have any items', i)
|
|
18
|
+
}
|
|
19
|
+
})
|
|
@@ -61,8 +61,8 @@ test('object or null body', t => {
|
|
|
61
61
|
method: 'POST',
|
|
62
62
|
url: '/',
|
|
63
63
|
handler: (req, reply) => {
|
|
64
|
-
t.equal(req.body,
|
|
65
|
-
reply.code(200).send({
|
|
64
|
+
t.equal(req.body, undefined)
|
|
65
|
+
reply.code(200).send({ isUndefinedBody: req.body === undefined })
|
|
66
66
|
},
|
|
67
67
|
schema: {
|
|
68
68
|
body: {
|
|
@@ -79,10 +79,8 @@ test('object or null body', t => {
|
|
|
79
79
|
type: 'object',
|
|
80
80
|
nullable: true,
|
|
81
81
|
properties: {
|
|
82
|
-
|
|
83
|
-
type: '
|
|
84
|
-
format: 'email',
|
|
85
|
-
nullable: true
|
|
82
|
+
isUndefinedBody: {
|
|
83
|
+
type: 'boolean'
|
|
86
84
|
}
|
|
87
85
|
}
|
|
88
86
|
}
|
|
@@ -100,7 +98,7 @@ test('object or null body', t => {
|
|
|
100
98
|
}, (err, response, body) => {
|
|
101
99
|
t.error(err)
|
|
102
100
|
t.equal(response.statusCode, 200)
|
|
103
|
-
t.same(JSON.parse(body), {
|
|
101
|
+
t.same(JSON.parse(body), { isUndefinedBody: true })
|
|
104
102
|
})
|
|
105
103
|
})
|
|
106
104
|
})
|
|
@@ -114,8 +112,8 @@ test('nullable body', t => {
|
|
|
114
112
|
method: 'POST',
|
|
115
113
|
url: '/',
|
|
116
114
|
handler: (req, reply) => {
|
|
117
|
-
t.equal(req.body,
|
|
118
|
-
reply.code(200).send({
|
|
115
|
+
t.equal(req.body, undefined)
|
|
116
|
+
reply.code(200).send({ isUndefinedBody: req.body === undefined })
|
|
119
117
|
},
|
|
120
118
|
schema: {
|
|
121
119
|
body: {
|
|
@@ -133,10 +131,8 @@ test('nullable body', t => {
|
|
|
133
131
|
type: 'object',
|
|
134
132
|
nullable: true,
|
|
135
133
|
properties: {
|
|
136
|
-
|
|
137
|
-
type: '
|
|
138
|
-
format: 'email',
|
|
139
|
-
nullable: true
|
|
134
|
+
isUndefinedBody: {
|
|
135
|
+
type: 'boolean'
|
|
140
136
|
}
|
|
141
137
|
}
|
|
142
138
|
}
|
|
@@ -154,7 +150,48 @@ test('nullable body', t => {
|
|
|
154
150
|
}, (err, response, body) => {
|
|
155
151
|
t.error(err)
|
|
156
152
|
t.equal(response.statusCode, 200)
|
|
157
|
-
t.same(JSON.parse(body), {
|
|
153
|
+
t.same(JSON.parse(body), { isUndefinedBody: true })
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
test('Nullable body with 204', t => {
|
|
159
|
+
t.plan(5)
|
|
160
|
+
|
|
161
|
+
const fastify = Fastify()
|
|
162
|
+
|
|
163
|
+
fastify.route({
|
|
164
|
+
method: 'POST',
|
|
165
|
+
url: '/',
|
|
166
|
+
handler: (req, reply) => {
|
|
167
|
+
t.equal(req.body, undefined)
|
|
168
|
+
reply.code(204).send()
|
|
169
|
+
},
|
|
170
|
+
schema: {
|
|
171
|
+
body: {
|
|
172
|
+
type: 'object',
|
|
173
|
+
nullable: true,
|
|
174
|
+
properties: {
|
|
175
|
+
hello: {
|
|
176
|
+
type: 'string',
|
|
177
|
+
format: 'email'
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
fastify.listen(0, (err) => {
|
|
185
|
+
fastify.server.unref()
|
|
186
|
+
t.error(err)
|
|
187
|
+
|
|
188
|
+
sget({
|
|
189
|
+
method: 'POST',
|
|
190
|
+
url: 'http://localhost:' + fastify.server.address().port
|
|
191
|
+
}, (err, response, body) => {
|
|
192
|
+
t.error(err)
|
|
193
|
+
t.equal(response.statusCode, 204)
|
|
194
|
+
t.equal(body.length, 0)
|
|
158
195
|
})
|
|
159
196
|
})
|
|
160
197
|
})
|