fastify 4.0.0-rc.4 → 4.0.0-rc.5
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/build/build-validation.js +12 -2
- package/docs/Guides/Index.md +1 -1
- package/docs/Reference/Server.md +32 -8
- package/docs/Reference/TypeScript.md +1 -1
- package/fastify.d.ts +1 -1
- package/fastify.js +36 -13
- package/lib/configValidator.js +402 -307
- package/lib/errors.js +4 -0
- package/lib/route.js +2 -1
- package/lib/validation.js +3 -1
- package/package.json +31 -31
- package/test/close-pipelining.test.js +4 -2
- package/test/close.test.js +93 -3
- package/test/custom-http-server.test.js +22 -0
- package/test/internals/initialConfig.test.js +0 -2
- package/test/output-validation.test.js +6 -2
- package/test/plugin.test.js +159 -0
- package/test/schema-serialization.test.js +27 -0
- package/test/types/logger.test-d.ts +13 -1
- package/test/types/type-provider.test-d.ts +6 -0
- package/types/logger.d.ts +3 -1
- package/types/schema.d.ts +1 -1
- package/types/type-provider.d.ts +2 -3
|
@@ -24,7 +24,7 @@ module.exports.defaultInitOptions = ${JSON.stringify(defaultInitOptions)}
|
|
|
24
24
|
const defaultInitOptions = {
|
|
25
25
|
connectionTimeout: 0, // 0 sec
|
|
26
26
|
keepAliveTimeout: 72000, // 72 seconds
|
|
27
|
-
forceCloseConnections:
|
|
27
|
+
forceCloseConnections: undefined, // keep-alive connections
|
|
28
28
|
maxRequestsPerSocket: 0, // no limit
|
|
29
29
|
requestTimeout: 0, // no limit
|
|
30
30
|
bodyLimit: 1024 * 1024, // 1 MiB
|
|
@@ -50,7 +50,17 @@ const schema = {
|
|
|
50
50
|
properties: {
|
|
51
51
|
connectionTimeout: { type: 'integer', default: defaultInitOptions.connectionTimeout },
|
|
52
52
|
keepAliveTimeout: { type: 'integer', default: defaultInitOptions.keepAliveTimeout },
|
|
53
|
-
forceCloseConnections: {
|
|
53
|
+
forceCloseConnections: {
|
|
54
|
+
oneOf: [
|
|
55
|
+
{
|
|
56
|
+
type: 'string',
|
|
57
|
+
pattern: 'idle'
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
type: 'boolean'
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
},
|
|
54
64
|
maxRequestsPerSocket: { type: 'integer', default: defaultInitOptions.maxRequestsPerSocket, nullable: true },
|
|
55
65
|
requestTimeout: { type: 'integer', default: defaultInitOptions.requestTimeout },
|
|
56
66
|
bodyLimit: { type: 'integer', default: defaultInitOptions.bodyLimit },
|
package/docs/Guides/Index.md
CHANGED
|
@@ -10,7 +10,7 @@ This table of contents is in alphabetical order.
|
|
|
10
10
|
+ [Contributing](./Contributing.md): Details how to participate in the
|
|
11
11
|
development of Fastify, and shows how to setup an environment compatible with
|
|
12
12
|
the project's code style.
|
|
13
|
-
+ [
|
|
13
|
+
+ [Delay Accepting Requests](./Delay-Accepting-Requests.md): A practical guide
|
|
14
14
|
on how to delay serving requests to specific routes until some condition is
|
|
15
15
|
met in your application. This guide focuses on solving the problem using
|
|
16
16
|
[`Hooks`](../Reference/Hooks.md), [`Decorators`](../Reference/Decorators.md),
|
package/docs/Reference/Server.md
CHANGED
|
@@ -60,6 +60,7 @@ describes the properties available in that options object.
|
|
|
60
60
|
- [addHook](#addhook)
|
|
61
61
|
- [prefix](#prefix)
|
|
62
62
|
- [pluginName](#pluginname)
|
|
63
|
+
- [hasPlugin](#hasplugin)
|
|
63
64
|
- [log](#log)
|
|
64
65
|
- [version](#version)
|
|
65
66
|
- [inject](#inject)
|
|
@@ -135,15 +136,18 @@ use. Also, when `serverFactory` option is specified, this option is ignored.
|
|
|
135
136
|
### `forceCloseConnections`
|
|
136
137
|
<a id="forcecloseconnections"></a>
|
|
137
138
|
|
|
138
|
-
When set to `true
|
|
139
|
-
|
|
140
|
-
current persistent connections and [destroy their
|
|
141
|
-
sockets](https://nodejs.org/dist/latest-v16.x/docs/api/net.html#socketdestroyerror).
|
|
142
|
-
This means the server will shutdown immediately instead of waiting for existing
|
|
143
|
-
persistent connections to timeout first. Important: connections are not
|
|
144
|
-
inspected to determine if requests have been completed.
|
|
139
|
+
When set to `true`, upon [`close`](#close) the server will iterate the
|
|
140
|
+
current persistent connections and [destroy their sockets](https://nodejs.org/dist/latest-v16.x/docs/api/net.html#socketdestroyerror).
|
|
145
141
|
|
|
146
|
-
|
|
142
|
+
> Important: connections are not inspected to determine if requests have been completed.
|
|
143
|
+
|
|
144
|
+
Fastify will prefer the HTTP server's [`closeAllConnections`](https://nodejs.org/dist/latest-v18.x/docs/api/http.html#servercloseallconnections) method if supported, otherwise it will use internal connection tracking.
|
|
145
|
+
|
|
146
|
+
When set to `"idle"`, upon [`close`](#close) the server will iterate the
|
|
147
|
+
current persistent connections which are not sending a request or waiting for a response and destroy their sockets.
|
|
148
|
+
The value is supported only if the HTTP server supports the [`closeIdleConnections`](https://nodejs.org/dist/latest-v18.x/docs/api/http.html#servercloseidleconnections) method, otherwise attempting to set it will throw an exception.
|
|
149
|
+
|
|
150
|
+
+ Default: `"idle"` if the HTTP server allows it, `false` otherwise
|
|
147
151
|
|
|
148
152
|
### `maxRequestsPerSocket`
|
|
149
153
|
<a id="factory-max-requests-per-socket"></a>
|
|
@@ -1105,6 +1109,26 @@ no new scope is created and therefore we have no place to attach contextual
|
|
|
1105
1109
|
data. In that case, the plugin name will represent the boot order of all
|
|
1106
1110
|
involved plugins in the format of `fastify -> plugin-A -> plugin-B`.
|
|
1107
1111
|
|
|
1112
|
+
#### hasPlugin
|
|
1113
|
+
<a id="hasPlugin"></a>
|
|
1114
|
+
|
|
1115
|
+
Method to check if a specific plugin has been registered.
|
|
1116
|
+
Relies on the plugin metadata name.
|
|
1117
|
+
Returns `true` if the plugin is registered.
|
|
1118
|
+
Otherwise, returns `false`.
|
|
1119
|
+
|
|
1120
|
+
```js
|
|
1121
|
+
const fastify = require('fastify')()
|
|
1122
|
+
fastify.register(require('@fastify/cookie'), {
|
|
1123
|
+
secret: 'my-secret',
|
|
1124
|
+
parseOptions: {}
|
|
1125
|
+
})
|
|
1126
|
+
|
|
1127
|
+
fastify.ready(() => {
|
|
1128
|
+
fastify.hasPlugin('@fastify/cookie') // true
|
|
1129
|
+
})
|
|
1130
|
+
```
|
|
1131
|
+
|
|
1108
1132
|
#### log
|
|
1109
1133
|
<a id="log"></a>
|
|
1110
1134
|
|
|
@@ -56,7 +56,7 @@ in a blank http Fastify server.
|
|
|
56
56
|
npx tsc --init
|
|
57
57
|
```
|
|
58
58
|
or use one of the [recommended
|
|
59
|
-
ones](https://github.com/tsconfig/bases#node-
|
|
59
|
+
ones](https://github.com/tsconfig/bases#node-14-tsconfigjson).
|
|
60
60
|
|
|
61
61
|
*Note: Set `target` property in `tsconfig.json` to `es2017` or greater to avoid
|
|
62
62
|
[FastifyDeprecation](https://github.com/fastify/fastify/issues/3284) warning.*
|
package/fastify.d.ts
CHANGED
|
@@ -110,7 +110,7 @@ export type FastifyServerOptions<
|
|
|
110
110
|
connectionTimeout?: number,
|
|
111
111
|
keepAliveTimeout?: number,
|
|
112
112
|
maxRequestsPerSocket?: number,
|
|
113
|
-
forceCloseConnections?: boolean,
|
|
113
|
+
forceCloseConnections?: boolean | 'idle',
|
|
114
114
|
requestTimeout?: number,
|
|
115
115
|
pluginTimeout?: number,
|
|
116
116
|
bodyLimit?: number,
|
package/fastify.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const VERSION = '4.0.0-rc.
|
|
3
|
+
const VERSION = '4.0.0-rc.5'
|
|
4
4
|
|
|
5
5
|
const Avvio = require('avvio')
|
|
6
6
|
const http = require('http')
|
|
@@ -52,6 +52,7 @@ const { defaultInitOptions } = getSecuredInitialConfig
|
|
|
52
52
|
|
|
53
53
|
const {
|
|
54
54
|
FST_ERR_BAD_URL,
|
|
55
|
+
FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE,
|
|
55
56
|
AVVIO_ERRORS_MAP,
|
|
56
57
|
appendStackTrace
|
|
57
58
|
} = require('./lib/errors')
|
|
@@ -123,7 +124,6 @@ function fastify (options) {
|
|
|
123
124
|
// Update the options with the fixed values
|
|
124
125
|
options.connectionTimeout = options.connectionTimeout || defaultInitOptions.connectionTimeout
|
|
125
126
|
options.keepAliveTimeout = options.keepAliveTimeout || defaultInitOptions.keepAliveTimeout
|
|
126
|
-
options.forceCloseConnections = typeof options.forceCloseConnections === 'boolean' ? options.forceCloseConnections : defaultInitOptions.forceCloseConnections
|
|
127
127
|
options.maxRequestsPerSocket = options.maxRequestsPerSocket || defaultInitOptions.maxRequestsPerSocket
|
|
128
128
|
options.requestTimeout = options.requestTimeout || defaultInitOptions.requestTimeout
|
|
129
129
|
options.logger = logger
|
|
@@ -135,7 +135,6 @@ function fastify (options) {
|
|
|
135
135
|
options.clientErrorHandler = options.clientErrorHandler || defaultClientErrorHandler
|
|
136
136
|
|
|
137
137
|
const initialConfig = getSecuredInitialConfig(options)
|
|
138
|
-
const keepAliveConnections = options.forceCloseConnections === true ? new Set() : noopSet()
|
|
139
138
|
|
|
140
139
|
// exposeHeadRoutes have its default set from the validator
|
|
141
140
|
options.exposeHeadRoutes = initialConfig.exposeHeadRoutes
|
|
@@ -172,8 +171,7 @@ function fastify (options) {
|
|
|
172
171
|
allowUnsafeRegex: options.allowUnsafeRegex || defaultInitOptions.allowUnsafeRegex,
|
|
173
172
|
buildPrettyMeta: defaultBuildPrettyMeta,
|
|
174
173
|
querystringParser: options.querystringParser
|
|
175
|
-
}
|
|
176
|
-
keepAliveConnections
|
|
174
|
+
}
|
|
177
175
|
})
|
|
178
176
|
|
|
179
177
|
// 404 router, used for handling encapsulated 404 handlers
|
|
@@ -186,6 +184,19 @@ function fastify (options) {
|
|
|
186
184
|
options.http2SessionTimeout = initialConfig.http2SessionTimeout
|
|
187
185
|
const { server, listen } = createServer(options, httpHandler)
|
|
188
186
|
|
|
187
|
+
const serverHasCloseAllConnections = typeof server.closeAllConnections === 'function'
|
|
188
|
+
const serverHasCloseIdleConnections = typeof server.closeIdleConnections === 'function'
|
|
189
|
+
|
|
190
|
+
let forceCloseConnections = options.forceCloseConnections
|
|
191
|
+
if (forceCloseConnections === 'idle' && !serverHasCloseIdleConnections) {
|
|
192
|
+
throw new FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE()
|
|
193
|
+
} else if (typeof forceCloseConnections !== 'boolean') {
|
|
194
|
+
/* istanbul ignore next: only one branch can be valid in a given Node.js version */
|
|
195
|
+
forceCloseConnections = serverHasCloseIdleConnections ? 'idle' : false
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const keepAliveConnections = !serverHasCloseAllConnections && forceCloseConnections === true ? new Set() : noopSet()
|
|
199
|
+
|
|
189
200
|
const setupResponseListeners = Reply.setupResponseListeners
|
|
190
201
|
const schemaController = SchemaController.buildSchemaController(null, options.schemaController)
|
|
191
202
|
|
|
@@ -285,6 +296,9 @@ function fastify (options) {
|
|
|
285
296
|
onClose: null,
|
|
286
297
|
close: null,
|
|
287
298
|
printPlugins: null,
|
|
299
|
+
hasPlugin: function (name) {
|
|
300
|
+
return this[kPluginNameChain].includes(name)
|
|
301
|
+
},
|
|
288
302
|
// http server
|
|
289
303
|
listen,
|
|
290
304
|
server,
|
|
@@ -386,13 +400,21 @@ function fastify (options) {
|
|
|
386
400
|
// No new TCP connections are accepted
|
|
387
401
|
instance.server.close(done)
|
|
388
402
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
403
|
+
/* istanbul ignore next: Cannot test this without Node.js core support */
|
|
404
|
+
if (forceCloseConnections === 'idle') {
|
|
405
|
+
instance.server.closeIdleConnections()
|
|
406
|
+
/* istanbul ignore next: Cannot test this without Node.js core support */
|
|
407
|
+
} else if (serverHasCloseAllConnections && forceCloseConnections) {
|
|
408
|
+
instance.server.closeAllConnections()
|
|
409
|
+
} else {
|
|
410
|
+
for (const conn of fastify[kKeepAliveConnections]) {
|
|
411
|
+
// We must invoke the destroy method instead of merely unreffing
|
|
412
|
+
// the sockets. If we only unref, then the callback passed to
|
|
413
|
+
// `fastify.close` will never be invoked; nor will any of the
|
|
414
|
+
// registered `onClose` hooks.
|
|
415
|
+
conn.destroy()
|
|
416
|
+
fastify[kKeepAliveConnections].delete(conn)
|
|
417
|
+
}
|
|
396
418
|
}
|
|
397
419
|
} else {
|
|
398
420
|
done(null)
|
|
@@ -411,7 +433,8 @@ function fastify (options) {
|
|
|
411
433
|
hasLogger,
|
|
412
434
|
setupResponseListeners,
|
|
413
435
|
throwIfAlreadyStarted,
|
|
414
|
-
validateHTTPVersion: compileValidateHTTPVersion(options)
|
|
436
|
+
validateHTTPVersion: compileValidateHTTPVersion(options),
|
|
437
|
+
keepAliveConnections
|
|
415
438
|
})
|
|
416
439
|
|
|
417
440
|
// Delay configuring clientError handler so that it can access fastify state.
|