fastify 4.19.1 → 4.20.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/.c8rc.json +8 -0
- package/.taprc +3 -2
- package/SECURITY.md +9 -0
- package/docs/Guides/Prototype-Poisoning.md +2 -2
- package/docs/Reference/Errors.md +39 -17
- package/docs/Reference/Logging.md +1 -1
- package/docs/Reference/Plugins.md +4 -0
- package/docs/Reference/Routes.md +8 -0
- package/docs/Reference/Server.md +38 -0
- package/fastify.d.ts +3 -2
- package/fastify.js +51 -24
- package/lib/context.js +6 -0
- package/lib/errors.js +50 -19
- package/lib/fourOhFour.js +5 -9
- package/lib/handleRequest.js +3 -5
- package/lib/hooks.js +91 -25
- package/lib/logger.js +40 -3
- package/lib/reply.js +3 -9
- package/lib/reqIdGenFactory.js +18 -3
- package/lib/route.js +14 -61
- package/lib/schema-controller.js +2 -0
- package/lib/server.js +23 -8
- package/lib/symbols.js +1 -0
- package/package.json +8 -7
- package/test/500s.test.js +22 -0
- package/test/childLoggerFactory.test.js +91 -0
- package/test/custom-http-server.test.js +42 -0
- package/test/encapsulated-child-logger-factory.test.js +69 -0
- package/test/fastify-instance.test.js +43 -10
- package/test/inject.test.js +1 -2
- package/test/internals/errors.test.js +843 -0
- package/test/internals/hookRunner.test.js +22 -8
- package/test/internals/initialConfig.test.js +9 -2
- package/test/internals/reply.test.js +49 -43
- package/test/internals/reqIdGenFactory.test.js +129 -0
- package/test/internals/request-validate.test.js +40 -1
- package/test/internals/request.test.js +14 -4
- package/test/reply-error.test.js +25 -0
- package/test/request-id.test.js +131 -0
- package/test/route.test.js +135 -0
- package/test/server.test.js +64 -2
- package/test/types/errors.test-d.ts +82 -0
- package/test/types/fastify.test-d.ts +4 -0
- package/test/types/hooks.test-d.ts +65 -64
- package/test/types/instance.test-d.ts +139 -0
- package/test/types/reply.test-d.ts +9 -8
- package/test/types/request.test-d.ts +17 -18
- package/test/types/route.test-d.ts +10 -7
- package/test/types/type-provider.test-d.ts +4 -0
- package/types/context.d.ts +3 -3
- package/types/errors.d.ts +29 -23
- package/types/instance.d.ts +39 -7
- package/types/logger.d.ts +25 -0
- package/types/reply.d.ts +10 -5
- package/types/request.d.ts +5 -5
- package/types/route.d.ts +8 -7
package/.c8rc.json
ADDED
package/.taprc
CHANGED
package/SECURITY.md
CHANGED
|
@@ -27,6 +27,15 @@ reported vulnerabilities:
|
|
|
27
27
|
validity of the report. In any case, the report should follow the same process
|
|
28
28
|
as outlined below of inviting the maintainers to review and accept the
|
|
29
29
|
vulnerability.
|
|
30
|
+
* ***Do not*** attempt to show CI/CD vulnerabilities by creating new pull
|
|
31
|
+
requests to any of the Fastify organization's repositories. Doing so will
|
|
32
|
+
result in a [content report][cr] to GitHub as an unsolicited exploit.
|
|
33
|
+
The proper way to provide such reports is by creating a new repository,
|
|
34
|
+
configured in the same manner as the repository you would like to submit
|
|
35
|
+
a report about, and with a pull request to your own repository showing
|
|
36
|
+
the proof of concept.
|
|
37
|
+
|
|
38
|
+
[cr]: https://docs.github.com/en/communities/maintaining-your-safety-on-github/reporting-abuse-or-spam#reporting-an-issue-or-pull-request
|
|
30
39
|
|
|
31
40
|
### Vulnerabilities found outside this process
|
|
32
41
|
|
|
@@ -13,8 +13,8 @@ open-source software and the limitations of existing communication channels.
|
|
|
13
13
|
|
|
14
14
|
But first, if we use a JavaScript framework to process incoming JSON data, take
|
|
15
15
|
a moment to read up on [Prototype Poisoning](https://medium.com/intrinsic/javascript-prototype-poisoning-vulnerabilities-in-the-wild-7bc15347c96)
|
|
16
|
-
in general, and the specific
|
|
17
|
-
(https://github.com/hapijs/hapi/issues/3916) of this issue.
|
|
16
|
+
in general, and the specific
|
|
17
|
+
[technical details](https://github.com/hapijs/hapi/issues/3916) of this issue.
|
|
18
18
|
This could be a critical issue so, we might need to verify your own code first.
|
|
19
19
|
It focuses on specific framework however, any solution that uses `JSON.parse()`
|
|
20
20
|
to process external data is potentially at risk.
|
package/docs/Reference/Errors.md
CHANGED
|
@@ -168,8 +168,6 @@ ajv.plugins option should be an array.
|
|
|
168
168
|
|
|
169
169
|
Version constraint should be a string.
|
|
170
170
|
|
|
171
|
-
<a name="FST_ERR_CTP_ALREADY_PRESENT"></a>
|
|
172
|
-
|
|
173
171
|
#### FST_ERR_CTP_ALREADY_PRESENT
|
|
174
172
|
<a id="FST_ERR_CTP_ALREADY_PRESENT"></a>
|
|
175
173
|
|
|
@@ -260,6 +258,11 @@ The hook name must be a string.
|
|
|
260
258
|
|
|
261
259
|
The hook callback must be a function.
|
|
262
260
|
|
|
261
|
+
#### FST_ERR_HOOK_INVALID_ASYNC_HANDLER
|
|
262
|
+
<a id="FST_ERR_HOOK_INVALID_ASYNC_HANDLER"></a>
|
|
263
|
+
|
|
264
|
+
Async function has too many arguments. Async hooks should not use the `done` argument.
|
|
265
|
+
|
|
263
266
|
#### FST_ERR_HOOK_NOT_SUPPORTED
|
|
264
267
|
<a id="FST_ERR_HOOK_NOT_SUPPORTED"></a>
|
|
265
268
|
|
|
@@ -271,8 +274,8 @@ The hook is not supported.
|
|
|
271
274
|
You must register a plugin for handling middlewares,
|
|
272
275
|
visit [`Middleware`](./Middleware.md) for more info.
|
|
273
276
|
|
|
274
|
-
<a name="FST_ERR_HOOK_TIMEOUT"></a>
|
|
275
277
|
#### FST_ERR_HOOK_TIMEOUT
|
|
278
|
+
<a id="FST_ERR_HOOK_TIMEOUT"></a>
|
|
276
279
|
|
|
277
280
|
A callback for a hook timed out
|
|
278
281
|
|
|
@@ -327,11 +330,21 @@ Called `reply.trailer` with an invalid header name.
|
|
|
327
330
|
|
|
328
331
|
Called `reply.trailer` with an invalid type. Expected a function.
|
|
329
332
|
|
|
333
|
+
#### FST_ERR_FAILED_ERROR_SERIALIZATION
|
|
334
|
+
<a id="FST_ERR_FAILED_ERROR_SERIALIZATION"></a>
|
|
335
|
+
|
|
336
|
+
Failed to serialize an error.
|
|
337
|
+
|
|
330
338
|
#### FST_ERR_MISSING_SERIALIZATION_FN
|
|
331
339
|
<a id="FST_ERR_MISSING_SERIALIZATION_FN"></a>
|
|
332
340
|
|
|
333
341
|
Missing serialization function.
|
|
334
342
|
|
|
343
|
+
#### FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN
|
|
344
|
+
<a id="FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN"></a>
|
|
345
|
+
|
|
346
|
+
Missing serialization function.
|
|
347
|
+
|
|
335
348
|
#### FST_ERR_REQ_INVALID_VALIDATION_INVOCATION
|
|
336
349
|
<a id="FST_ERR_REQ_INVALID_VALIDATION_INVOCATION"></a>
|
|
337
350
|
|
|
@@ -348,6 +361,11 @@ The schema provided does not have `$id` property.
|
|
|
348
361
|
|
|
349
362
|
A schema with the same `$id` already exists.
|
|
350
363
|
|
|
364
|
+
#### FST_ERR_SCH_CONTENT_MISSING_SCHEMA
|
|
365
|
+
<a id="FST_ERR_SCH_CONTENT_MISSING_SCHEMA"></a>
|
|
366
|
+
|
|
367
|
+
A schema is missing for the corresponding content type.
|
|
368
|
+
|
|
351
369
|
#### FST_ERR_SCH_DUPLICATE
|
|
352
370
|
<a id="FST_ERR_SCH_DUPLICATE"></a>
|
|
353
371
|
|
|
@@ -384,8 +402,8 @@ Invalid initialization options.
|
|
|
384
402
|
Cannot set forceCloseConnections to `idle` as your HTTP server
|
|
385
403
|
does not support `closeIdleConnections` method.
|
|
386
404
|
|
|
387
|
-
<a name="FST_ERR_DUPLICATED_ROUTE"></a>
|
|
388
405
|
#### FST_ERR_DUPLICATED_ROUTE
|
|
406
|
+
<a id="FST_ERR_DUPLICATED_ROUTE"></a>
|
|
389
407
|
|
|
390
408
|
The HTTP method already has a registered controller for that URL
|
|
391
409
|
|
|
@@ -394,7 +412,7 @@ The HTTP method already has a registered controller for that URL
|
|
|
394
412
|
|
|
395
413
|
The router received an invalid url.
|
|
396
414
|
|
|
397
|
-
|
|
415
|
+
#### FST_ERR_ASYNC_CONSTRAINT
|
|
398
416
|
<a id="FST_ERR_ASYNC_CONSTRAINT"></a>
|
|
399
417
|
|
|
400
418
|
The router received an error when using asynchronous constraints.
|
|
@@ -469,38 +487,42 @@ Fastify is already listening.
|
|
|
469
487
|
|
|
470
488
|
Installed Fastify plugin mismatched expected version.
|
|
471
489
|
|
|
472
|
-
<a name="FST_ERR_PLUGIN_CALLBACK_NOT_FN"></a>
|
|
473
|
-
|
|
474
490
|
#### FST_ERR_PLUGIN_CALLBACK_NOT_FN
|
|
491
|
+
<a id="FST_ERR_PLUGIN_CALLBACK_NOT_FN"></a>
|
|
475
492
|
|
|
476
493
|
Callback for a hook is not a function (mapped directly from `avvio`)
|
|
477
494
|
|
|
478
|
-
<a name="FST_ERR_PLUGIN_NOT_VALID"></a>
|
|
479
|
-
|
|
480
495
|
#### FST_ERR_PLUGIN_NOT_VALID
|
|
496
|
+
<a id="FST_ERR_PLUGIN_NOT_VALID"></a>
|
|
481
497
|
|
|
482
498
|
Plugin must be a function or a promise.
|
|
483
499
|
|
|
484
|
-
<a name="FST_ERR_ROOT_PLG_BOOTED"></a>
|
|
485
|
-
|
|
486
500
|
#### FST_ERR_ROOT_PLG_BOOTED
|
|
501
|
+
<a id="FST_ERR_ROOT_PLG_BOOTED"></a>
|
|
487
502
|
|
|
488
503
|
Root plugin has already booted (mapped directly from `avvio`)
|
|
489
504
|
|
|
490
|
-
<a name="FST_ERR_PARENT_PLUGIN_BOOTED"></a>
|
|
491
|
-
|
|
492
505
|
#### FST_ERR_PARENT_PLUGIN_BOOTED
|
|
506
|
+
<a id="FST_ERR_PARENT_PLUGIN_BOOTED"></a>
|
|
493
507
|
|
|
494
508
|
Impossible to load plugin because the parent (mapped directly from `avvio`)
|
|
495
509
|
|
|
496
|
-
<a name="FST_ERR_PLUGIN_TIMEOUT"></a>
|
|
497
|
-
|
|
498
510
|
#### FST_ERR_PLUGIN_TIMEOUT
|
|
511
|
+
<a id="FST_ERR_PLUGIN_TIMEOUT"></a>
|
|
499
512
|
|
|
500
513
|
Plugin did not start in time. Default timeout (in millis): `10000`
|
|
501
514
|
|
|
502
|
-
<a name="FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE"></a>
|
|
503
|
-
|
|
504
515
|
#### FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE
|
|
516
|
+
<a id="FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE"></a>
|
|
505
517
|
|
|
506
518
|
The decorator is not present in the instance.
|
|
519
|
+
|
|
520
|
+
#### FST_ERR_VALIDATION
|
|
521
|
+
<a id="FST_ERR_VALIDATION"></a>
|
|
522
|
+
|
|
523
|
+
The Request failed the payload validation.
|
|
524
|
+
|
|
525
|
+
#### FST_ERR_LISTEN_OPTIONS_INVALID
|
|
526
|
+
<a id="FST_ERR_LISTEN_OPTIONS_INVALID"></a>
|
|
527
|
+
|
|
528
|
+
Invalid listen options.
|
|
@@ -196,7 +196,7 @@ app.addHook('preHandler', function (req, reply, done) {
|
|
|
196
196
|
})
|
|
197
197
|
```
|
|
198
198
|
|
|
199
|
-
**Note**: Care should be
|
|
199
|
+
**Note**: Care should be taken to ensure serializers never throw, as an error
|
|
200
200
|
thrown from a serializer has the potential to cause the Node process to exit.
|
|
201
201
|
See the [Pino documentation](https://getpino.io/#/docs/api?id=opt-serializers)
|
|
202
202
|
on serializers for more information.
|
|
@@ -145,6 +145,10 @@ await fastify.ready()
|
|
|
145
145
|
|
|
146
146
|
await fastify.listen({ port: 3000 })
|
|
147
147
|
```
|
|
148
|
+
*Note: Using `await` when registering a plugin loads the plugin
|
|
149
|
+
and the underlying dependency tree, "finalizing" the encapsulation process.
|
|
150
|
+
Any mutations to the plugin after it and its dependencies have been
|
|
151
|
+
loaded will not be reflected in the parent instance.*
|
|
148
152
|
|
|
149
153
|
#### ESM support
|
|
150
154
|
<a id="esm-support"></a>
|
package/docs/Reference/Routes.md
CHANGED
|
@@ -90,6 +90,14 @@ fastify.route(options)
|
|
|
90
90
|
To access the default handler, you can access `instance.errorHandler`. Note
|
|
91
91
|
that this will point to fastify's default `errorHandler` only if a plugin
|
|
92
92
|
hasn't overridden it already.
|
|
93
|
+
* `childLoggerFactory(logger, binding, opts, rawReq)`: a custom factory function
|
|
94
|
+
that will be called to produce a child logger instance for every request.
|
|
95
|
+
See [`childLoggerFactory`](./Server.md#childloggerfactory) for more info.
|
|
96
|
+
Overrides the default logger factory, and anything set by
|
|
97
|
+
[`setChildLoggerFactory`](./Server.md#setchildloggerfactory), for requests to
|
|
98
|
+
the route. To access the default factory, you can access
|
|
99
|
+
`instance.childLoggerFactory`. Note that this will point to Fastify's default
|
|
100
|
+
`childLoggerFactory` only if a plugin hasn't overridden it already.
|
|
93
101
|
* `validatorCompiler({ schema, method, url, httpPart })`: function that builds
|
|
94
102
|
schemas for request validations. See the [Validation and
|
|
95
103
|
Serialization](./Validation-and-Serialization.md#schema-validator)
|
package/docs/Reference/Server.md
CHANGED
|
@@ -80,6 +80,7 @@ describes the properties available in that options object.
|
|
|
80
80
|
- [schemaController](#schemacontroller)
|
|
81
81
|
- [setNotFoundHandler](#setnotfoundhandler)
|
|
82
82
|
- [setErrorHandler](#seterrorhandler)
|
|
83
|
+
- [setChildLoggerFactory](#setchildloggerfactory)
|
|
83
84
|
- [addConstraintStrategy](#addconstraintstrategy)
|
|
84
85
|
- [hasConstraintStrategy](#hasconstraintstrategy)
|
|
85
86
|
- [printRoutes](#printroutes)
|
|
@@ -91,6 +92,7 @@ describes the properties available in that options object.
|
|
|
91
92
|
- [getDefaultJsonParser](#getdefaultjsonparser)
|
|
92
93
|
- [defaultTextParser](#defaulttextparser)
|
|
93
94
|
- [errorHandler](#errorhandler)
|
|
95
|
+
- [childLoggerFactory](#childloggerfactory)
|
|
94
96
|
- [initialConfig](#initialconfig)
|
|
95
97
|
|
|
96
98
|
### `http`
|
|
@@ -1537,6 +1539,35 @@ if (statusCode >= 500) {
|
|
|
1537
1539
|
log.error(error)
|
|
1538
1540
|
}
|
|
1539
1541
|
```
|
|
1542
|
+
#### setChildLoggerFactory
|
|
1543
|
+
<a id="set-child-logger-factory"></a>
|
|
1544
|
+
|
|
1545
|
+
`fastify.setChildLoggerFactory(factory(logger, bindings, opts, rawReq))`: Set a
|
|
1546
|
+
function that will be called when creating a child logger instance for each request
|
|
1547
|
+
which allows for modifying or adding child logger bindings and logger options, or
|
|
1548
|
+
returning a completely custom child logger implementation.
|
|
1549
|
+
|
|
1550
|
+
Child logger bindings have a performance advantage over per-log bindings, because
|
|
1551
|
+
they are pre-serialised by Pino when the child logger is created.
|
|
1552
|
+
|
|
1553
|
+
The first parameter is the parent logger instance, followed by the default bindings
|
|
1554
|
+
and logger options which should be passed to the child logger, and finally
|
|
1555
|
+
the raw request (not a Fastify request object). The function is bound with `this`
|
|
1556
|
+
being the Fastify instance.
|
|
1557
|
+
|
|
1558
|
+
For example:
|
|
1559
|
+
```js
|
|
1560
|
+
const fastify = require('fastify')({
|
|
1561
|
+
childLoggerFactory: function (logger, bindings, opts, rawReq) {
|
|
1562
|
+
// Calculate additional bindings from the request if needed
|
|
1563
|
+
bindings.traceContext = rawReq.headers['x-cloud-trace-context']
|
|
1564
|
+
return logger.child(bindings, opts)
|
|
1565
|
+
}
|
|
1566
|
+
})
|
|
1567
|
+
```
|
|
1568
|
+
|
|
1569
|
+
The handler is bound to the Fastify instance and is fully encapsulated, so
|
|
1570
|
+
different plugins can set different logger factories.
|
|
1540
1571
|
|
|
1541
1572
|
#### addConstraintStrategy
|
|
1542
1573
|
<a id="addConstraintStrategy"></a>
|
|
@@ -1810,6 +1841,13 @@ fastify.get('/', {
|
|
|
1810
1841
|
}, handler)
|
|
1811
1842
|
```
|
|
1812
1843
|
|
|
1844
|
+
#### childLoggerFactory
|
|
1845
|
+
<a id="childLoggerFactory"></a>
|
|
1846
|
+
|
|
1847
|
+
`fastify.childLoggerFactory` returns the custom logger factory function for the
|
|
1848
|
+
Fastify instance. See the [`childLoggerFactory` config option](#setchildloggerfactory)
|
|
1849
|
+
for more info.
|
|
1850
|
+
|
|
1813
1851
|
#### initialConfig
|
|
1814
1852
|
<a id="initial-config"></a>
|
|
1815
1853
|
|
package/fastify.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { FastifyContext, FastifyContextConfig } from './types/context'
|
|
|
14
14
|
import { FastifyErrorCodes } from './types/errors'
|
|
15
15
|
import { DoneFuncWithErrOrRes, HookHandlerDoneFunction, RequestPayload, onCloseAsyncHookHandler, onCloseHookHandler, onErrorAsyncHookHandler, onErrorHookHandler, onReadyAsyncHookHandler, onReadyHookHandler, onRegisterHookHandler, onRequestAsyncHookHandler, onRequestHookHandler, onResponseAsyncHookHandler, onResponseHookHandler, onRouteHookHandler, onSendAsyncHookHandler, onSendHookHandler, onTimeoutAsyncHookHandler, onTimeoutHookHandler, preHandlerAsyncHookHandler, preHandlerHookHandler, preParsingAsyncHookHandler, preParsingHookHandler, preSerializationAsyncHookHandler, preSerializationHookHandler, preValidationAsyncHookHandler, preValidationHookHandler, onRequestAbortHookHandler, onRequestAbortAsyncHookHandler } from './types/hooks'
|
|
16
16
|
import { FastifyListenOptions, FastifyInstance, PrintRoutesOptions } from './types/instance'
|
|
17
|
-
import { FastifyBaseLogger, FastifyLoggerInstance, FastifyLoggerOptions, PinoLoggerOptions, FastifyLogFn, LogLevel } from './types/logger'
|
|
17
|
+
import { FastifyBaseLogger, FastifyLoggerInstance, FastifyLoggerOptions, PinoLoggerOptions, FastifyLogFn, LogLevel, Bindings, ChildLoggerOptions } from './types/logger'
|
|
18
18
|
import { FastifyPluginCallback, FastifyPluginAsync, FastifyPluginOptions, FastifyPlugin } from './types/plugin'
|
|
19
19
|
import { FastifyRegister, FastifyRegisterOptions, RegisterOptions } from './types/register'
|
|
20
20
|
import { FastifyReply } from './types/reply'
|
|
@@ -106,6 +106,7 @@ declare namespace fastify {
|
|
|
106
106
|
serializerOpts?: FJSOptions | Record<string, unknown>,
|
|
107
107
|
serverFactory?: FastifyServerFactory<RawServer>,
|
|
108
108
|
caseSensitive?: boolean,
|
|
109
|
+
allowUnsafeRegex?: boolean,
|
|
109
110
|
requestIdHeader?: string | false,
|
|
110
111
|
requestIdLogLabel?: string;
|
|
111
112
|
jsonShorthand?: boolean;
|
|
@@ -158,7 +159,7 @@ declare namespace fastify {
|
|
|
158
159
|
/**
|
|
159
160
|
* listener to error events emitted by client connections
|
|
160
161
|
*/
|
|
161
|
-
clientErrorHandler?: (error: ConnectionError, socket: Socket) => void
|
|
162
|
+
clientErrorHandler?: (error: ConnectionError, socket: Socket) => void,
|
|
162
163
|
}
|
|
163
164
|
|
|
164
165
|
export interface ValidationResult {
|
package/fastify.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const VERSION = '4.
|
|
3
|
+
const VERSION = '4.20.0'
|
|
4
4
|
|
|
5
5
|
const Avvio = require('avvio')
|
|
6
6
|
const http = require('http')
|
|
@@ -28,20 +28,21 @@ const {
|
|
|
28
28
|
kSchemaErrorFormatter,
|
|
29
29
|
kErrorHandler,
|
|
30
30
|
kKeepAliveConnections,
|
|
31
|
-
|
|
31
|
+
kChildLoggerFactory
|
|
32
32
|
} = require('./lib/symbols.js')
|
|
33
33
|
|
|
34
34
|
const { createServer, compileValidateHTTPVersion } = require('./lib/server')
|
|
35
35
|
const Reply = require('./lib/reply')
|
|
36
36
|
const Request = require('./lib/request')
|
|
37
|
+
const Context = require('./lib/context.js')
|
|
37
38
|
const { supportedMethods } = require('./lib/httpMethods')
|
|
38
39
|
const decorator = require('./lib/decorate')
|
|
39
40
|
const ContentTypeParser = require('./lib/contentTypeParser')
|
|
40
41
|
const SchemaController = require('./lib/schema-controller')
|
|
41
42
|
const { Hooks, hookRunnerApplication, supportedHooks } = require('./lib/hooks')
|
|
42
|
-
const { createLogger } = require('./lib/logger')
|
|
43
|
+
const { createLogger, createChildLogger, defaultChildLoggerFactory } = require('./lib/logger')
|
|
43
44
|
const pluginUtils = require('./lib/pluginUtils')
|
|
44
|
-
const reqIdGenFactory = require('./lib/reqIdGenFactory')
|
|
45
|
+
const { reqIdGenFactory } = require('./lib/reqIdGenFactory')
|
|
45
46
|
const { buildRouting, validateBodyLimitOption } = require('./lib/route')
|
|
46
47
|
const build404 = require('./lib/fourOhFour')
|
|
47
48
|
const getSecuredInitialConfig = require('./lib/initialConfigValidation')
|
|
@@ -74,14 +75,6 @@ const {
|
|
|
74
75
|
|
|
75
76
|
const { buildErrorHandler } = require('./lib/error-handler.js')
|
|
76
77
|
|
|
77
|
-
const onBadUrlContext = {
|
|
78
|
-
config: {
|
|
79
|
-
},
|
|
80
|
-
onSend: [],
|
|
81
|
-
onError: [],
|
|
82
|
-
[kFourOhFourContext]: null
|
|
83
|
-
}
|
|
84
|
-
|
|
85
78
|
function defaultBuildPrettyMeta (route) {
|
|
86
79
|
// return a shallow copy of route's sanitized context
|
|
87
80
|
|
|
@@ -95,6 +88,9 @@ function defaultBuildPrettyMeta (route) {
|
|
|
95
88
|
return Object.assign({}, cleanKeys)
|
|
96
89
|
}
|
|
97
90
|
|
|
91
|
+
/**
|
|
92
|
+
* @param {import('./fastify.js').FastifyServerOptions} options
|
|
93
|
+
*/
|
|
98
94
|
function fastify (options) {
|
|
99
95
|
// Options validations
|
|
100
96
|
options = options || {}
|
|
@@ -113,7 +109,7 @@ function fastify (options) {
|
|
|
113
109
|
|
|
114
110
|
validateBodyLimitOption(options.bodyLimit)
|
|
115
111
|
|
|
116
|
-
const requestIdHeader = (options.requestIdHeader === false) ? false : (options.requestIdHeader || defaultInitOptions.requestIdHeader)
|
|
112
|
+
const requestIdHeader = (options.requestIdHeader === false) ? false : (options.requestIdHeader || defaultInitOptions.requestIdHeader).toLowerCase()
|
|
117
113
|
const genReqId = reqIdGenFactory(requestIdHeader, options.genReqId)
|
|
118
114
|
const requestIdLogLabel = options.requestIdLogLabel || 'reqId'
|
|
119
115
|
const bodyLimit = options.bodyLimit || defaultInitOptions.bodyLimit
|
|
@@ -235,6 +231,7 @@ function fastify (options) {
|
|
|
235
231
|
[kSchemaController]: schemaController,
|
|
236
232
|
[kSchemaErrorFormatter]: null,
|
|
237
233
|
[kErrorHandler]: buildErrorHandler(),
|
|
234
|
+
[kChildLoggerFactory]: defaultChildLoggerFactory,
|
|
238
235
|
[kReplySerializerDefault]: null,
|
|
239
236
|
[kContentTypeParser]: new ContentTypeParser(
|
|
240
237
|
bodyLimit,
|
|
@@ -340,6 +337,8 @@ function fastify (options) {
|
|
|
340
337
|
// custom error handling
|
|
341
338
|
setNotFoundHandler,
|
|
342
339
|
setErrorHandler,
|
|
340
|
+
// child logger
|
|
341
|
+
setChildLoggerFactory,
|
|
343
342
|
// Set fastify initial configuration options read-only object
|
|
344
343
|
initialConfig,
|
|
345
344
|
// constraint strategies
|
|
@@ -351,11 +350,13 @@ function fastify (options) {
|
|
|
351
350
|
listeningOrigin: {
|
|
352
351
|
get () {
|
|
353
352
|
const address = this.addresses().slice(-1).pop()
|
|
354
|
-
/*
|
|
353
|
+
/* ignore if windows: unix socket is not testable on Windows platform */
|
|
354
|
+
/* c8 ignore next 3 */
|
|
355
355
|
if (typeof address === 'string') {
|
|
356
356
|
return address
|
|
357
357
|
}
|
|
358
|
-
|
|
358
|
+
const host = address.family === 'IPv6' ? `[${address.address}]` : address.address
|
|
359
|
+
return `${this[kOptions].https ? 'https' : 'http'}://${host}:${address.port}`
|
|
359
360
|
}
|
|
360
361
|
},
|
|
361
362
|
pluginName: {
|
|
@@ -379,6 +380,10 @@ function fastify (options) {
|
|
|
379
380
|
configurable: true,
|
|
380
381
|
get () { return this[kSchemaController].getSerializerCompiler() }
|
|
381
382
|
},
|
|
383
|
+
childLoggerFactory: {
|
|
384
|
+
configurable: true,
|
|
385
|
+
get () { return this[kChildLoggerFactory] }
|
|
386
|
+
},
|
|
382
387
|
version: {
|
|
383
388
|
configurable: true,
|
|
384
389
|
get () { return VERSION }
|
|
@@ -426,12 +431,6 @@ function fastify (options) {
|
|
|
426
431
|
router.closeRoutes()
|
|
427
432
|
|
|
428
433
|
hookRunnerApplication('preClose', fastify[kAvvioBoot], fastify, function () {
|
|
429
|
-
// No new TCP connections are accepted.
|
|
430
|
-
// We must call close on the server even if we are not listening
|
|
431
|
-
// otherwise memory will be leaked.
|
|
432
|
-
// https://github.com/nodejs/node/issues/48604
|
|
433
|
-
instance.server.close(done)
|
|
434
|
-
|
|
435
434
|
if (fastify[kState].listening) {
|
|
436
435
|
/* istanbul ignore next: Cannot test this without Node.js core support */
|
|
437
436
|
if (forceCloseConnections === 'idle') {
|
|
@@ -450,13 +449,34 @@ function fastify (options) {
|
|
|
450
449
|
fastify[kKeepAliveConnections].delete(conn)
|
|
451
450
|
}
|
|
452
451
|
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// No new TCP connections are accepted.
|
|
455
|
+
// We must call close on the server even if we are not listening
|
|
456
|
+
// otherwise memory will be leaked.
|
|
457
|
+
// https://github.com/nodejs/node/issues/48604
|
|
458
|
+
if (!options.serverFactory || fastify[kState].listening) {
|
|
459
|
+
instance.server.close(function (err) {
|
|
460
|
+
/* c8 ignore next 6 */
|
|
461
|
+
if (err && err.code !== 'ERR_SERVER_NOT_RUNNING') {
|
|
462
|
+
done(null)
|
|
463
|
+
} else {
|
|
464
|
+
done()
|
|
465
|
+
}
|
|
466
|
+
})
|
|
453
467
|
} else {
|
|
454
|
-
done
|
|
468
|
+
process.nextTick(done, null)
|
|
455
469
|
}
|
|
456
470
|
})
|
|
457
471
|
})
|
|
458
472
|
})
|
|
459
473
|
|
|
474
|
+
// Create bad URL context
|
|
475
|
+
const onBadUrlContext = new Context({
|
|
476
|
+
server: fastify,
|
|
477
|
+
config: {}
|
|
478
|
+
})
|
|
479
|
+
|
|
460
480
|
// Set the default 404 handler
|
|
461
481
|
fastify.setNotFoundHandler()
|
|
462
482
|
fourOhFour.arrange404(fastify)
|
|
@@ -698,7 +718,7 @@ function fastify (options) {
|
|
|
698
718
|
function onBadUrl (path, req, res) {
|
|
699
719
|
if (frameworkErrors) {
|
|
700
720
|
const id = genReqId(req)
|
|
701
|
-
const childLogger =
|
|
721
|
+
const childLogger = createChildLogger(onBadUrlContext, logger, req, id)
|
|
702
722
|
|
|
703
723
|
const request = new Request(id, null, req, null, childLogger, onBadUrlContext)
|
|
704
724
|
const reply = new Reply(res, request, childLogger)
|
|
@@ -723,7 +743,7 @@ function fastify (options) {
|
|
|
723
743
|
if (err) {
|
|
724
744
|
if (frameworkErrors) {
|
|
725
745
|
const id = genReqId(req)
|
|
726
|
-
const childLogger =
|
|
746
|
+
const childLogger = createChildLogger(onBadUrlContext, logger, req, id)
|
|
727
747
|
|
|
728
748
|
const request = new Request(id, null, req, null, childLogger, onBadUrlContext)
|
|
729
749
|
const reply = new Reply(res, request, childLogger)
|
|
@@ -795,6 +815,13 @@ function fastify (options) {
|
|
|
795
815
|
return this
|
|
796
816
|
}
|
|
797
817
|
|
|
818
|
+
function setChildLoggerFactory (factory) {
|
|
819
|
+
throwIfAlreadyStarted('Cannot call "setChildLoggerFactory"!')
|
|
820
|
+
|
|
821
|
+
this[kChildLoggerFactory] = factory
|
|
822
|
+
return this
|
|
823
|
+
}
|
|
824
|
+
|
|
798
825
|
function printRoutes (opts = {}) {
|
|
799
826
|
// includeHooks:true - shortcut to include all supported hooks exported by fastify.Hooks
|
|
800
827
|
opts.includeMeta = opts.includeHooks ? opts.includeMeta ? supportedHooks.concat(opts.includeMeta) : supportedHooks : opts.includeMeta
|
package/lib/context.js
CHANGED
|
@@ -5,6 +5,8 @@ const {
|
|
|
5
5
|
kReplySerializerDefault,
|
|
6
6
|
kSchemaErrorFormatter,
|
|
7
7
|
kErrorHandler,
|
|
8
|
+
kChildLoggerFactory,
|
|
9
|
+
kOptions,
|
|
8
10
|
kReply,
|
|
9
11
|
kRequest,
|
|
10
12
|
kBodyLimit,
|
|
@@ -22,6 +24,8 @@ function Context ({
|
|
|
22
24
|
schema,
|
|
23
25
|
handler,
|
|
24
26
|
config,
|
|
27
|
+
requestIdLogLabel,
|
|
28
|
+
childLoggerFactory,
|
|
25
29
|
errorHandler,
|
|
26
30
|
bodyLimit,
|
|
27
31
|
logLevel,
|
|
@@ -51,6 +55,8 @@ function Context ({
|
|
|
51
55
|
this.onRequestAbort = null
|
|
52
56
|
this.config = config
|
|
53
57
|
this.errorHandler = errorHandler || server[kErrorHandler]
|
|
58
|
+
this.requestIdLogLabel = requestIdLogLabel || server[kOptions].requestIdLogLabel
|
|
59
|
+
this.childLoggerFactory = childLoggerFactory || server[kChildLoggerFactory]
|
|
54
60
|
this._middie = null
|
|
55
61
|
this._parserOptions = {
|
|
56
62
|
limit: bodyLimit || server[kBodyLimit]
|