fastify 4.24.0 → 4.24.2

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.
Files changed (54) hide show
  1. package/fastify.js +1 -1
  2. package/lib/route.js +10 -4
  3. package/package.json +32 -32
  4. package/test/404s.test.js +31 -39
  5. package/test/async-await.test.js +1 -1
  6. package/test/build-certificate.js +90 -1
  7. package/test/close-pipelining.test.js +5 -5
  8. package/test/close.test.js +1 -5
  9. package/test/custom-http-server.test.js +94 -91
  10. package/test/custom-parser.0.test.js +21 -47
  11. package/test/custom-parser.1.test.js +10 -732
  12. package/test/custom-parser.2.test.js +102 -0
  13. package/test/custom-parser.3.test.js +245 -0
  14. package/test/custom-parser.4.test.js +239 -0
  15. package/test/custom-parser.5.test.js +149 -0
  16. package/test/head.test.js +204 -0
  17. package/test/helper.js +30 -8
  18. package/test/hooks-async.test.js +3 -3
  19. package/test/hooks.on-listen.test.js +7 -6
  20. package/test/hooks.test.js +4 -15
  21. package/test/http2/closing.test.js +7 -15
  22. package/test/https/custom-https-server.test.js +43 -40
  23. package/test/listen.1.test.js +101 -0
  24. package/test/listen.2.test.js +103 -0
  25. package/test/listen.3.test.js +87 -0
  26. package/test/listen.4.test.js +164 -0
  27. package/test/listen.deprecated.test.js +3 -9
  28. package/test/logger/instantiation.test.js +25 -16
  29. package/test/logger/logger-test-utils.js +1 -1
  30. package/test/plugin.1.test.js +249 -0
  31. package/test/plugin.2.test.js +328 -0
  32. package/test/plugin.3.test.js +311 -0
  33. package/test/plugin.4.test.js +416 -0
  34. package/test/reply-trailers.test.js +1 -2
  35. package/test/route.1.test.js +309 -0
  36. package/test/route.2.test.js +99 -0
  37. package/test/route.3.test.js +205 -0
  38. package/test/route.4.test.js +131 -0
  39. package/test/route.5.test.js +230 -0
  40. package/test/route.6.test.js +306 -0
  41. package/test/route.7.test.js +370 -0
  42. package/test/route.8.test.js +142 -0
  43. package/test/stream.1.test.js +108 -0
  44. package/test/stream.2.test.js +119 -0
  45. package/test/stream.3.test.js +192 -0
  46. package/test/stream.4.test.js +223 -0
  47. package/test/stream.5.test.js +194 -0
  48. package/test/trust-proxy.test.js +2 -4
  49. package/test/upgrade.test.js +3 -3
  50. package/types/instance.d.ts +2 -0
  51. package/test/listen.test.js +0 -427
  52. package/test/plugin.test.js +0 -1275
  53. package/test/route.test.js +0 -1762
  54. package/test/stream.test.js +0 -816
package/fastify.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const VERSION = '4.24.0'
3
+ const VERSION = '4.24.2'
4
4
 
5
5
  const Avvio = require('avvio')
6
6
  const http = require('node:http')
package/lib/route.js CHANGED
@@ -182,8 +182,14 @@ function buildRouting (options) {
182
182
  const { exposeHeadRoute } = opts
183
183
  const hasRouteExposeHeadRouteFlag = exposeHeadRoute != null
184
184
  const shouldExposeHead = hasRouteExposeHeadRouteFlag ? exposeHeadRoute : globalExposeHeadRoutes
185
+
186
+ const isGetRoute = opts.method === 'GET' ||
187
+ (Array.isArray(opts.method) && opts.method.includes('GET'))
188
+ const isHeadRoute = opts.method === 'HEAD' ||
189
+ (Array.isArray(opts.method) && opts.method.includes('HEAD'))
190
+
185
191
  // we need to clone a set of initial options for HEAD route
186
- const headOpts = shouldExposeHead && options.method === 'GET' ? { ...options } : null
192
+ const headOpts = shouldExposeHead && isGetRoute ? { ...options } : null
187
193
 
188
194
  throwIfAlreadyStarted('Cannot add route!')
189
195
 
@@ -326,8 +332,8 @@ function buildRouting (options) {
326
332
  const hasHEADHandler = headHandler !== null
327
333
 
328
334
  // remove the head route created by fastify
329
- if (hasHEADHandler && !context[kRouteByFastify] && headHandler.store[kRouteByFastify]) {
330
- router.off('HEAD', opts.url, { constraints })
335
+ if (isHeadRoute && hasHEADHandler && !context[kRouteByFastify] && headHandler.store[kRouteByFastify]) {
336
+ router.off('HEAD', opts.url, constraints)
331
337
  }
332
338
 
333
339
  try {
@@ -407,7 +413,7 @@ function buildRouting (options) {
407
413
  // register head route in sync
408
414
  // we must place it after the `this.after`
409
415
 
410
- if (shouldExposeHead && options.method === 'GET' && !hasHEADHandler) {
416
+ if (shouldExposeHead && isGetRoute && !isHeadRoute && !hasHEADHandler) {
411
417
  const onSendHandlers = parseHeadOnSendHandlers(headOpts.onSend)
412
418
  prepareRoute.call(this, { method: 'HEAD', url: path, options: { ...headOpts, onSend: onSendHandlers }, isFastify: true })
413
419
  } else if (hasHEADHandler && exposeHeadRoute) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fastify",
3
- "version": "4.24.0",
3
+ "version": "4.24.2",
4
4
  "description": "Fast and low overhead web framework, for Node.js",
5
5
  "main": "fastify.js",
6
6
  "type": "commonjs",
@@ -29,7 +29,7 @@
29
29
  "unit": "c8 tap",
30
30
  "unit:junit": "tap-mocha-reporter xunit < out.tap > test/junit-testresults.xml",
31
31
  "unit:report": "tap --cov --coverage-report=html --coverage-report=cobertura | tee out.tap",
32
- "citgm": "tap"
32
+ "citgm": "tap --jobs=1"
33
33
  },
34
34
  "repository": {
35
35
  "type": "git",
@@ -144,66 +144,66 @@
144
144
  "homepage": "https://www.fastify.dev/",
145
145
  "devDependencies": {
146
146
  "@fastify/pre-commit": "^2.0.2",
147
- "@sinclair/typebox": "^0.31.1",
148
- "@sinonjs/fake-timers": "^11.0.0",
149
- "@types/node": "^20.1.0",
150
- "@typescript-eslint/eslint-plugin": "^6.3.0",
151
- "@typescript-eslint/parser": "^6.3.0",
147
+ "@sinclair/typebox": "^0.31.17",
148
+ "@sinonjs/fake-timers": "^11.1.0",
149
+ "@types/node": "^20.8.4",
150
+ "@typescript-eslint/eslint-plugin": "^6.7.5",
151
+ "@typescript-eslint/parser": "^6.7.5",
152
152
  "ajv": "^8.12.0",
153
153
  "ajv-errors": "^3.0.0",
154
154
  "ajv-formats": "^2.1.1",
155
155
  "ajv-i18n": "^4.2.0",
156
156
  "ajv-merge-patch": "^5.0.1",
157
157
  "branch-comparer": "^1.1.0",
158
- "c8": "^8.0.0",
158
+ "c8": "^8.0.1",
159
159
  "cross-env": "^7.0.3",
160
- "eslint": "^8.39.0",
161
- "eslint-config-standard": "^17.0.0",
162
- "eslint-import-resolver-node": "^0.3.7",
163
- "eslint-plugin-import": "^2.27.5",
164
- "eslint-plugin-n": "^16.0.1",
160
+ "eslint": "^8.51.0",
161
+ "eslint-config-standard": "^17.1.0",
162
+ "eslint-import-resolver-node": "^0.3.9",
163
+ "eslint-plugin-import": "^2.28.1",
164
+ "eslint-plugin-n": "^16.2.0",
165
165
  "eslint-plugin-promise": "^6.1.1",
166
166
  "fast-json-body": "^1.1.0",
167
- "fastify-plugin": "^4.5.0",
168
- "fluent-json-schema": "^4.1.0",
167
+ "fastify-plugin": "^4.5.1",
168
+ "fluent-json-schema": "^4.1.2",
169
169
  "form-data": "^4.0.0",
170
170
  "h2url": "^0.2.0",
171
171
  "http-errors": "^2.0.0",
172
- "joi": "^17.9.2",
173
- "json-schema-to-ts": "^2.9.1",
172
+ "joi": "^17.11.0",
173
+ "json-schema-to-ts": "^2.9.2",
174
174
  "JSONStream": "^1.3.5",
175
- "markdownlint-cli2": "^0.9.2",
175
+ "markdownlint-cli2": "^0.10.0",
176
+ "node-forge": "^1.3.1",
176
177
  "proxyquire": "^2.1.3",
177
- "self-cert": "^2.0.0",
178
178
  "send": "^0.18.0",
179
179
  "simple-get": "^4.0.1",
180
180
  "snazzy": "^9.0.0",
181
181
  "split2": "^4.2.0",
182
- "standard": "^17.0.0",
183
- "tap": "^16.3.4",
182
+ "standard": "^17.1.0",
183
+ "tap": "^16.3.9",
184
184
  "tsd": "^0.29.0",
185
- "typescript": "^5.0.4",
186
- "undici": "^5.22.0",
185
+ "typescript": "^5.2.2",
186
+ "undici": "^5.26.0",
187
187
  "vary": "^1.1.2",
188
- "yup": "^1.1.1"
188
+ "yup": "^1.3.2"
189
189
  },
190
190
  "dependencies": {
191
191
  "@fastify/ajv-compiler": "^3.5.0",
192
- "@fastify/error": "^3.2.0",
192
+ "@fastify/error": "^3.4.0",
193
193
  "@fastify/fast-json-stringify-compiler": "^4.3.0",
194
194
  "abstract-logging": "^2.0.1",
195
195
  "avvio": "^8.2.1",
196
- "fast-content-type-parse": "^1.0.0",
197
- "fast-json-stringify": "^5.7.0",
196
+ "fast-content-type-parse": "^1.1.0",
197
+ "fast-json-stringify": "^5.8.0",
198
198
  "find-my-way": "^7.7.0",
199
- "light-my-request": "^5.9.1",
200
- "pino": "^8.12.0",
199
+ "light-my-request": "^5.11.0",
200
+ "pino": "^8.16.0",
201
201
  "process-warning": "^2.2.0",
202
202
  "proxy-addr": "^2.0.7",
203
203
  "rfdc": "^1.3.0",
204
- "secure-json-parse": "^2.5.0",
205
- "semver": "^7.5.0",
206
- "toad-cache": "^3.2.0"
204
+ "secure-json-parse": "^2.7.0",
205
+ "semver": "^7.5.4",
206
+ "toad-cache": "^3.3.0"
207
207
  },
208
208
  "standard": {
209
209
  "ignore": [
package/test/404s.test.js CHANGED
@@ -8,15 +8,7 @@ const errors = require('http-errors')
8
8
  const split = require('split2')
9
9
  const FormData = require('form-data')
10
10
  const Fastify = require('..')
11
-
12
- function getUrl (app) {
13
- const { address, port } = app.server.address()
14
- if (address === '::1') {
15
- return `http://[${address}]:${port}`
16
- } else {
17
- return `http://${address}:${port}`
18
- }
19
- }
11
+ const { getServerUrl } = require('./helper')
20
12
 
21
13
  test('default 404', t => {
22
14
  t.plan(5)
@@ -37,7 +29,7 @@ test('default 404', t => {
37
29
  t.plan(3)
38
30
  sget({
39
31
  method: 'PUT',
40
- url: getUrl(fastify),
32
+ url: getServerUrl(fastify),
41
33
  body: {},
42
34
  json: true
43
35
  }, (err, response, body) => {
@@ -52,7 +44,7 @@ test('default 404', t => {
52
44
  t.plan(3)
53
45
  sget({
54
46
  method: 'PROPFIND',
55
- url: getUrl(fastify),
47
+ url: getServerUrl(fastify),
56
48
  body: {},
57
49
  json: true
58
50
  }, (err, response, body) => {
@@ -66,7 +58,7 @@ test('default 404', t => {
66
58
  t.plan(3)
67
59
  sget({
68
60
  method: 'GET',
69
- url: getUrl(fastify) + '/notSupported',
61
+ url: getServerUrl(fastify) + '/notSupported',
70
62
  body: {},
71
63
  json: true
72
64
  }, (err, response, body) => {
@@ -83,7 +75,7 @@ test('default 404', t => {
83
75
 
84
76
  sget({
85
77
  method: 'POST',
86
- url: getUrl(fastify) + '/notSupported',
78
+ url: getServerUrl(fastify) + '/notSupported',
87
79
  body: form,
88
80
  json: false
89
81
  }, (err, response, body) => {
@@ -128,7 +120,7 @@ test('customized 404', t => {
128
120
  t.plan(3)
129
121
  sget({
130
122
  method: 'PUT',
131
- url: getUrl(fastify),
123
+ url: getServerUrl(fastify),
132
124
  body: JSON.stringify({ hello: 'world' }),
133
125
  headers: { 'Content-Type': 'application/json' }
134
126
  }, (err, response, body) => {
@@ -142,7 +134,7 @@ test('customized 404', t => {
142
134
  t.plan(3)
143
135
  sget({
144
136
  method: 'PROPFIND',
145
- url: getUrl(fastify),
137
+ url: getServerUrl(fastify),
146
138
  body: JSON.stringify({ hello: 'world' }),
147
139
  headers: { 'Content-Type': 'application/json' }
148
140
  }, (err, response, body) => {
@@ -156,7 +148,7 @@ test('customized 404', t => {
156
148
  t.plan(3)
157
149
  sget({
158
150
  method: 'GET',
159
- url: getUrl(fastify) + '/notSupported'
151
+ url: getServerUrl(fastify) + '/notSupported'
160
152
  }, (err, response, body) => {
161
153
  t.error(err)
162
154
  t.equal(response.statusCode, 404)
@@ -168,7 +160,7 @@ test('customized 404', t => {
168
160
  t.plan(3)
169
161
  sget({
170
162
  method: 'GET',
171
- url: getUrl(fastify) + '/with-error'
163
+ url: getServerUrl(fastify) + '/with-error'
172
164
  }, (err, response, body) => {
173
165
  t.error(err)
174
166
  t.equal(response.statusCode, 404)
@@ -184,7 +176,7 @@ test('customized 404', t => {
184
176
  t.plan(4)
185
177
  sget({
186
178
  method: 'GET',
187
- url: getUrl(fastify) + '/with-error-custom-header'
179
+ url: getServerUrl(fastify) + '/with-error-custom-header'
188
180
  }, (err, response, body) => {
189
181
  t.error(err)
190
182
  t.equal(response.statusCode, 404)
@@ -218,7 +210,7 @@ test('custom header in notFound handler', t => {
218
210
  t.plan(4)
219
211
  sget({
220
212
  method: 'GET',
221
- url: getUrl(fastify) + '/notSupported'
213
+ url: getServerUrl(fastify) + '/notSupported'
222
214
  }, (err, response, body) => {
223
215
  t.error(err)
224
216
  t.equal(response.statusCode, 404)
@@ -405,7 +397,7 @@ test('encapsulated 404', t => {
405
397
  t.plan(3)
406
398
  sget({
407
399
  method: 'PUT',
408
- url: getUrl(fastify),
400
+ url: getServerUrl(fastify),
409
401
  body: JSON.stringify({ hello: 'world' }),
410
402
  headers: { 'Content-Type': 'application/json' }
411
403
  }, (err, response, body) => {
@@ -419,7 +411,7 @@ test('encapsulated 404', t => {
419
411
  t.plan(3)
420
412
  sget({
421
413
  method: 'PROPFIND',
422
- url: getUrl(fastify),
414
+ url: getServerUrl(fastify),
423
415
  body: JSON.stringify({ hello: 'world' }),
424
416
  headers: { 'Content-Type': 'application/json' }
425
417
  }, (err, response, body) => {
@@ -433,7 +425,7 @@ test('encapsulated 404', t => {
433
425
  t.plan(3)
434
426
  sget({
435
427
  method: 'GET',
436
- url: getUrl(fastify) + '/notSupported'
428
+ url: getServerUrl(fastify) + '/notSupported'
437
429
  }, (err, response, body) => {
438
430
  t.error(err)
439
431
  t.equal(response.statusCode, 404)
@@ -445,7 +437,7 @@ test('encapsulated 404', t => {
445
437
  t.plan(3)
446
438
  sget({
447
439
  method: 'PUT',
448
- url: getUrl(fastify) + '/test',
440
+ url: getServerUrl(fastify) + '/test',
449
441
  body: JSON.stringify({ hello: 'world' }),
450
442
  headers: { 'Content-Type': 'application/json' }
451
443
  }, (err, response, body) => {
@@ -459,7 +451,7 @@ test('encapsulated 404', t => {
459
451
  t.plan(3)
460
452
  sget({
461
453
  method: 'PROPFIND',
462
- url: getUrl(fastify) + '/test',
454
+ url: getServerUrl(fastify) + '/test',
463
455
  body: JSON.stringify({ hello: 'world' }),
464
456
  headers: { 'Content-Type': 'application/json' }
465
457
  }, (err, response, body) => {
@@ -473,7 +465,7 @@ test('encapsulated 404', t => {
473
465
  t.plan(3)
474
466
  sget({
475
467
  method: 'GET',
476
- url: getUrl(fastify) + '/test/notSupported'
468
+ url: getServerUrl(fastify) + '/test/notSupported'
477
469
  }, (err, response, body) => {
478
470
  t.error(err)
479
471
  t.equal(response.statusCode, 404)
@@ -485,7 +477,7 @@ test('encapsulated 404', t => {
485
477
  t.plan(3)
486
478
  sget({
487
479
  method: 'PUT',
488
- url: getUrl(fastify) + '/test2',
480
+ url: getServerUrl(fastify) + '/test2',
489
481
  body: JSON.stringify({ hello: 'world' }),
490
482
  headers: { 'Content-Type': 'application/json' }
491
483
  }, (err, response, body) => {
@@ -499,7 +491,7 @@ test('encapsulated 404', t => {
499
491
  t.plan(3)
500
492
  sget({
501
493
  method: 'PROPFIND',
502
- url: getUrl(fastify) + '/test2',
494
+ url: getServerUrl(fastify) + '/test2',
503
495
  body: JSON.stringify({ hello: 'world' }),
504
496
  headers: { 'Content-Type': 'application/json' }
505
497
  }, (err, response, body) => {
@@ -513,7 +505,7 @@ test('encapsulated 404', t => {
513
505
  t.plan(3)
514
506
  sget({
515
507
  method: 'GET',
516
- url: getUrl(fastify) + '/test2/notSupported'
508
+ url: getServerUrl(fastify) + '/test2/notSupported'
517
509
  }, (err, response, body) => {
518
510
  t.error(err)
519
511
  t.equal(response.statusCode, 404)
@@ -525,7 +517,7 @@ test('encapsulated 404', t => {
525
517
  t.plan(3)
526
518
  sget({
527
519
  method: 'PUT',
528
- url: getUrl(fastify) + '/test3/',
520
+ url: getServerUrl(fastify) + '/test3/',
529
521
  body: JSON.stringify({ hello: 'world' }),
530
522
  headers: { 'Content-Type': 'application/json' }
531
523
  }, (err, response, body) => {
@@ -539,7 +531,7 @@ test('encapsulated 404', t => {
539
531
  t.plan(3)
540
532
  sget({
541
533
  method: 'PROPFIND',
542
- url: getUrl(fastify) + '/test3/',
534
+ url: getServerUrl(fastify) + '/test3/',
543
535
  body: JSON.stringify({ hello: 'world' }),
544
536
  headers: { 'Content-Type': 'application/json' }
545
537
  }, (err, response, body) => {
@@ -553,7 +545,7 @@ test('encapsulated 404', t => {
553
545
  t.plan(3)
554
546
  sget({
555
547
  method: 'GET',
556
- url: getUrl(fastify) + '/test3/notSupported'
548
+ url: getServerUrl(fastify) + '/test3/notSupported'
557
549
  }, (err, response, body) => {
558
550
  t.error(err)
559
551
  t.equal(response.statusCode, 404)
@@ -717,7 +709,7 @@ test('run hooks on default 404', t => {
717
709
 
718
710
  sget({
719
711
  method: 'PUT',
720
- url: getUrl(fastify),
712
+ url: getServerUrl(fastify),
721
713
  body: JSON.stringify({ hello: 'world' }),
722
714
  headers: { 'Content-Type': 'application/json' }
723
715
  }, (err, response, body) => {
@@ -878,7 +870,7 @@ test('run hook with encapsulated 404', t => {
878
870
 
879
871
  sget({
880
872
  method: 'PUT',
881
- url: getUrl(fastify) + '/test',
873
+ url: getServerUrl(fastify) + '/test',
882
874
  body: JSON.stringify({ hello: 'world' }),
883
875
  headers: { 'Content-Type': 'application/json' }
884
876
  }, (err, response, body) => {
@@ -948,7 +940,7 @@ test('run hook with encapsulated 404 and framework-unsupported method', t => {
948
940
 
949
941
  sget({
950
942
  method: 'PROPFIND',
951
- url: getUrl(fastify) + '/test',
943
+ url: getServerUrl(fastify) + '/test',
952
944
  body: JSON.stringify({ hello: 'world' }),
953
945
  headers: { 'Content-Type': 'application/json' }
954
946
  }, (err, response, body) => {
@@ -988,7 +980,7 @@ test('hooks check 404', t => {
988
980
 
989
981
  sget({
990
982
  method: 'PUT',
991
- url: getUrl(fastify) + '?foo=asd',
983
+ url: getServerUrl(fastify) + '?foo=asd',
992
984
  body: JSON.stringify({ hello: 'world' }),
993
985
  headers: { 'Content-Type': 'application/json' }
994
986
  }, (err, response, body) => {
@@ -998,7 +990,7 @@ test('hooks check 404', t => {
998
990
 
999
991
  sget({
1000
992
  method: 'GET',
1001
- url: getUrl(fastify) + '/notSupported?foo=asd'
993
+ url: getServerUrl(fastify) + '/notSupported?foo=asd'
1002
994
  }, (err, response, body) => {
1003
995
  t.error(err)
1004
996
  t.equal(response.statusCode, 404)
@@ -1095,7 +1087,7 @@ test('Unknown method', t => {
1095
1087
 
1096
1088
  sget({
1097
1089
  method: 'UNKNWON_METHOD',
1098
- url: getUrl(fastify)
1090
+ url: getServerUrl(fastify)
1099
1091
  }, (err, response, body) => {
1100
1092
  t.error(err)
1101
1093
  t.equal(response.statusCode, 400)
@@ -1129,7 +1121,7 @@ test('recognizes errors from the http-errors module', t => {
1129
1121
  t.error(err)
1130
1122
  t.equal(res.statusCode, 404)
1131
1123
 
1132
- sget(getUrl(fastify), (err, response, body) => {
1124
+ sget(getServerUrl(fastify), (err, response, body) => {
1133
1125
  t.error(err)
1134
1126
  const obj = JSON.parse(body.toString())
1135
1127
  t.strictSame(obj, {
@@ -1276,7 +1268,7 @@ test('404 inside onSend', t => {
1276
1268
 
1277
1269
  sget({
1278
1270
  method: 'GET',
1279
- url: getUrl(fastify)
1271
+ url: getServerUrl(fastify)
1280
1272
  }, (err, response, body) => {
1281
1273
  t.error(err)
1282
1274
  t.equal(response.statusCode, 404)
@@ -6,8 +6,8 @@ const sget = require('simple-get').concat
6
6
  const Fastify = require('..')
7
7
  const split = require('split2')
8
8
  const pino = require('pino')
9
+ const { sleep } = require('./helper')
9
10
  const statusCodes = require('node:http').STATUS_CODES
10
- const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
11
11
 
12
12
  const opts = {
13
13
  schema: {
@@ -1,6 +1,95 @@
1
1
  'use strict'
2
2
 
3
- const selfCert = require('self-cert')
3
+ const os = require('os')
4
+ const forge = require('node-forge')
5
+
6
+ // from self-cert module
7
+ function selfCert (opts) {
8
+ const options = opts || {}
9
+ const log = opts.logger || require('abstract-logging')
10
+ const now = new Date()
11
+
12
+ if (!options.attrs) options.attrs = {}
13
+ if (!options.expires) {
14
+ options.expires = new Date(
15
+ now.getFullYear() + 5, now.getMonth() + 1, now.getDate()
16
+ )
17
+ }
18
+
19
+ log.debug('generating key pair')
20
+ const keys = forge.pki.rsa.generateKeyPair(options.bits || 2048)
21
+ log.debug('key pair generated')
22
+
23
+ log.debug('generating self-signed certificate')
24
+ const cert = forge.pki.createCertificate()
25
+ cert.publicKey = keys.publicKey
26
+ cert.serialNumber = '01'
27
+ cert.validity.notBefore = now
28
+ cert.validity.notAfter = options.expires
29
+
30
+ const attrs = [
31
+ { name: 'commonName', value: options.attrs.commonName || os.hostname() },
32
+ { name: 'countryName', value: options.attrs.countryName || 'US' },
33
+ { name: 'stateOrProvinceName', value: options.attrs.stateName || 'Georgia' },
34
+ { name: 'localityName', value: options.attrs.locality || 'Atlanta' },
35
+ { name: 'organizationName', value: options.attrs.orgName || 'None' },
36
+ { shortName: 'OU', value: options.attrs.shortName || 'example' }
37
+ ]
38
+ cert.setSubject(attrs)
39
+ cert.setIssuer(attrs)
40
+
41
+ cert.setExtensions([
42
+ { name: 'basicConstraints', cA: true },
43
+ {
44
+ name: 'keyUsage',
45
+ keyCertSign: true,
46
+ digitalSignature: true,
47
+ nonRepudiation: true,
48
+ keyEncipherment: true,
49
+ dataEncipherment: true
50
+ },
51
+ {
52
+ name: 'extKeyUsage',
53
+ serverAuth: true,
54
+ clientAuth: true,
55
+ codeSigning: true,
56
+ emailProtection: true,
57
+ timeStamping: true
58
+ },
59
+ {
60
+ name: 'nsCertType',
61
+ client: true,
62
+ server: true,
63
+ email: true,
64
+ objsign: true,
65
+ sslCA: true,
66
+ emailCA: true,
67
+ objCA: true
68
+ },
69
+ { name: 'subjectKeyIdentifier' },
70
+ {
71
+ name: 'subjectAltName',
72
+ altNames: [{ type: 6 /* URI */, value: 'DNS: ' + attrs[0].value }].concat((function () {
73
+ const interfaces = os.networkInterfaces()
74
+
75
+ // fix citgm: skip invalid ips (aix72-ppc64)
76
+ const ips = Object.values(interfaces).flat()
77
+ .filter(i => !!forge.util.bytesFromIP(i.address))
78
+ .map(i => ({ type: 7 /* IP */, ip: i.address }))
79
+
80
+ return ips
81
+ }()))
82
+ }
83
+ ])
84
+
85
+ cert.sign(keys.privateKey)
86
+ log.debug('certificate generated')
87
+ return {
88
+ privateKey: forge.pki.privateKeyToPem(keys.privateKey),
89
+ publicKey: forge.pki.publicKeyToPem(keys.publicKey),
90
+ certificate: forge.pki.certificateToPem(cert)
91
+ }
92
+ }
4
93
 
5
94
  async function buildCertificate () {
6
95
  // "global" is used in here because "t.context" is only supported by "t.beforeEach" and "t.afterEach"
@@ -36,8 +36,8 @@ test('Should return 503 while closing - pipelining', async t => {
36
36
  await instance.close()
37
37
  })
38
38
 
39
- const isV19plus = semver.gte(process.version, '19.0.0')
40
- test('Should not return 503 while closing - pipelining - return503OnClosing: false, skip Node >= v19.x', { skip: isV19plus }, async t => {
39
+ const isVgte19 = semver.gte(process.version, '19.0.0')
40
+ test('Should not return 503 while closing - pipelining - return503OnClosing: false, skip Node >= v19.x', { skip: isVgte19 }, async t => {
41
41
  const fastify = Fastify({
42
42
  return503OnClosing: false,
43
43
  forceCloseConnections: false
@@ -67,7 +67,7 @@ test('Should not return 503 while closing - pipelining - return503OnClosing: fal
67
67
  await instance.close()
68
68
  })
69
69
 
70
- test('Should close the socket abruptly - pipelining - return503OnClosing: false, skip Node < v19.x', { skip: !isV19plus }, async t => {
70
+ test('Should close the socket abruptly - pipelining - return503OnClosing: false, skip Node < v19.x', { skip: !isVgte19 }, async t => {
71
71
  // Since Node v19, we will always invoke server.closeIdleConnections()
72
72
  // therefore our socket will be closed
73
73
  const fastify = Fastify({
@@ -75,9 +75,9 @@ test('Should close the socket abruptly - pipelining - return503OnClosing: false,
75
75
  forceCloseConnections: false
76
76
  })
77
77
 
78
- fastify.get('/', (req, reply) => {
79
- fastify.close()
78
+ fastify.get('/', async (req, reply) => {
80
79
  reply.send({ hello: 'world' })
80
+ fastify.close()
81
81
  })
82
82
 
83
83
  await fastify.listen({ port: 0 })
@@ -7,6 +7,7 @@ const Fastify = require('..')
7
7
  const { Client } = require('undici')
8
8
  const semver = require('semver')
9
9
  const split = require('split2')
10
+ const { sleep } = require('./helper')
10
11
 
11
12
  test('close callback', t => {
12
13
  t.plan(4)
@@ -687,11 +688,6 @@ test('preClose async', async t => {
687
688
 
688
689
  test('preClose execution order', t => {
689
690
  t.plan(4)
690
- async function sleep (ms) {
691
- return new Promise((resolve) => {
692
- setTimeout(resolve, ms)
693
- })
694
- }
695
691
  const fastify = Fastify()
696
692
  const order = []
697
693
  fastify.addHook('onClose', onClose)