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.
@@ -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: false, // keep-alive connections
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: { type: 'boolean', default: defaultInitOptions.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 },
@@ -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
- + [`Delay Accepting Requests`](./Delay-Accepting-Requests.md): A practical guide
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),
@@ -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` requests with the header `connection: keep-alive` will be
139
- tracked by the server. Upon [`close`](#close), the server will iterate the
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
- + Default: `false`
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-10-tsconfigjson).
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.4'
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
- for (const conn of fastify[kKeepAliveConnections]) {
390
- // We must invoke the destroy method instead of merely unreffing
391
- // the sockets. If we only unref, then the callback passed to
392
- // `fastify.close` will never be invoked; nor will any of the
393
- // registered `onClose` hooks.
394
- conn.destroy()
395
- fastify[kKeepAliveConnections].delete(conn)
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.