fastify 5.0.0 → 5.2.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.
Files changed (201) hide show
  1. package/.borp.yaml +3 -0
  2. package/.vscode/settings.json +22 -0
  3. package/README.md +12 -7
  4. package/docs/Guides/Database.md +15 -15
  5. package/docs/Guides/Detecting-When-Clients-Abort.md +28 -28
  6. package/docs/Guides/Ecosystem.md +14 -15
  7. package/docs/Guides/Index.md +1 -1
  8. package/docs/Guides/Migration-Guide-V4.md +11 -11
  9. package/docs/Guides/Migration-Guide-V5.md +133 -9
  10. package/docs/Guides/Plugins-Guide.md +1 -1
  11. package/docs/Guides/Prototype-Poisoning.md +3 -3
  12. package/docs/Guides/Recommendations.md +9 -9
  13. package/docs/Guides/Serverless.md +5 -5
  14. package/docs/Guides/Testing.md +58 -57
  15. package/docs/Guides/Write-Plugin.md +2 -2
  16. package/docs/Guides/Write-Type-Provider.md +3 -3
  17. package/docs/Reference/ContentTypeParser.md +4 -4
  18. package/docs/Reference/Decorators.md +2 -2
  19. package/docs/Reference/Errors.md +3 -3
  20. package/docs/Reference/Hooks.md +7 -7
  21. package/docs/Reference/LTS.md +8 -0
  22. package/docs/Reference/Logging.md +5 -4
  23. package/docs/Reference/Reply.md +55 -58
  24. package/docs/Reference/Request.md +49 -42
  25. package/docs/Reference/Routes.md +16 -13
  26. package/docs/Reference/Server.md +32 -28
  27. package/docs/Reference/TypeScript.md +9 -9
  28. package/docs/Reference/Validation-and-Serialization.md +5 -5
  29. package/examples/typescript-server.ts +1 -1
  30. package/fastify.d.ts +14 -5
  31. package/fastify.js +8 -6
  32. package/lib/contentTypeParser.js +9 -7
  33. package/lib/context.js +1 -2
  34. package/lib/error-handler.js +9 -9
  35. package/lib/errors.js +1 -1
  36. package/lib/fourOhFour.js +1 -1
  37. package/lib/hooks.js +4 -1
  38. package/lib/{logger.js → logger-factory.js} +70 -122
  39. package/lib/logger-pino.js +68 -0
  40. package/lib/pluginOverride.js +1 -1
  41. package/lib/pluginUtils.js +2 -2
  42. package/lib/reply.js +4 -5
  43. package/lib/request.js +16 -9
  44. package/lib/route.js +23 -22
  45. package/lib/validation.js +2 -2
  46. package/package.json +13 -15
  47. package/test/404s.test.js +675 -629
  48. package/test/500s.test.js +72 -63
  49. package/test/{allowUnsafeRegex.test.js → allow-unsafe-regex.test.js} +30 -26
  50. package/test/als.test.js +48 -45
  51. package/test/async-await.test.js +148 -134
  52. package/test/async-dispose.test.js +4 -5
  53. package/test/async_hooks.test.js +30 -28
  54. package/test/{bodyLimit.test.js → body-limit.test.js} +61 -58
  55. package/test/buffer.test.js +9 -10
  56. package/test/build/error-serializer.test.js +3 -4
  57. package/test/build/version.test.js +2 -3
  58. package/test/build-certificate.js +1 -1
  59. package/test/bundler/README.md +5 -5
  60. package/test/bundler/esbuild/bundler-test.js +10 -9
  61. package/test/bundler/webpack/bundler-test.js +10 -9
  62. package/test/case-insensitive.test.js +31 -28
  63. package/test/chainable.test.js +4 -5
  64. package/test/check.test.js +8 -10
  65. package/test/{childLoggerFactory.test.js → child-logger-factory.test.js} +56 -19
  66. package/test/client-timeout.test.js +5 -5
  67. package/test/close-pipelining.test.js +6 -8
  68. package/test/conditional-pino.test.js +47 -0
  69. package/test/{connectionTimeout.test.js → connection-timeout.test.js} +10 -11
  70. package/test/constrained-routes.test.js +243 -236
  71. package/test/content-length.test.js +53 -68
  72. package/test/content-parser.test.js +186 -158
  73. package/test/content-type.test.js +8 -9
  74. package/test/context-config.test.js +44 -54
  75. package/test/custom-http-server.test.js +16 -20
  76. package/test/custom-parser.5.test.js +32 -32
  77. package/test/diagnostics-channel/404.test.js +15 -15
  78. package/test/diagnostics-channel/async-delay-request.test.js +25 -25
  79. package/test/diagnostics-channel/async-request.test.js +24 -24
  80. package/test/diagnostics-channel/error-before-handler.test.js +4 -5
  81. package/test/diagnostics-channel/error-request.test.js +19 -19
  82. package/test/diagnostics-channel/error-status.test.js +8 -8
  83. package/test/diagnostics-channel/init.test.js +6 -7
  84. package/test/diagnostics-channel/sync-delay-request.test.js +16 -16
  85. package/test/diagnostics-channel/sync-request-reply.test.js +16 -16
  86. package/test/diagnostics-channel/sync-request.test.js +19 -19
  87. package/test/encapsulated-child-logger-factory.test.js +8 -8
  88. package/test/encapsulated-error-handler.test.js +20 -20
  89. package/test/esm/errorCodes.test.mjs +5 -5
  90. package/test/esm/esm.test.mjs +3 -3
  91. package/test/esm/named-exports.mjs +3 -3
  92. package/test/esm/other.mjs +2 -2
  93. package/test/fastify-instance.test.js +33 -34
  94. package/test/{findRoute.test.js → find-route.test.js} +11 -10
  95. package/test/fluent-schema.test.js +33 -36
  96. package/test/handler-context.test.js +11 -11
  97. package/test/has-route.test.js +12 -15
  98. package/test/header-overflow.test.js +13 -12
  99. package/test/hooks.on-ready.test.js +2 -2
  100. package/test/hooks.test.js +25 -25
  101. package/test/http-methods/copy.test.js +22 -24
  102. package/test/http-methods/custom-http-methods.test.js +24 -21
  103. package/test/http-methods/get.test.js +97 -84
  104. package/test/http-methods/head.test.js +63 -57
  105. package/test/http-methods/lock.test.js +21 -20
  106. package/test/http-methods/mkcalendar.test.js +31 -27
  107. package/test/http-methods/mkcol.test.js +10 -10
  108. package/test/http-methods/move.test.js +11 -11
  109. package/test/http-methods/propfind.test.js +32 -27
  110. package/test/http-methods/proppatch.test.js +21 -19
  111. package/test/http-methods/report.test.js +32 -27
  112. package/test/http-methods/search.test.js +52 -47
  113. package/test/http-methods/trace.test.js +3 -4
  114. package/test/http-methods/unlock.test.js +10 -10
  115. package/test/http2/closing.test.js +50 -58
  116. package/test/http2/constraint.test.js +47 -50
  117. package/test/http2/head.test.js +18 -19
  118. package/test/http2/missing-http2-module.test.js +4 -5
  119. package/test/http2/plain.test.js +31 -31
  120. package/test/http2/secure-with-fallback.test.js +61 -61
  121. package/test/http2/secure.test.js +28 -31
  122. package/test/http2/unknown-http-method.test.js +13 -14
  123. package/test/https/custom-https-server.test.js +6 -7
  124. package/test/https/https.test.js +78 -78
  125. package/test/imports.test.js +5 -6
  126. package/test/internals/all.test.js +8 -11
  127. package/test/internals/{contentTypeParser.test.js → content-type-parser.test.js} +5 -6
  128. package/test/internals/context.test.js +9 -11
  129. package/test/internals/decorator.test.js +20 -21
  130. package/test/internals/errors.test.js +427 -427
  131. package/test/internals/{handleRequest.test.js → handle-request.test.js} +53 -42
  132. package/test/internals/{hookRunner.test.js → hook-runner.test.js} +99 -100
  133. package/test/internals/hooks.test.js +31 -35
  134. package/test/internals/{initialConfig.test.js → initial-config.test.js} +92 -80
  135. package/test/internals/logger.test.js +28 -28
  136. package/test/internals/plugin.test.js +17 -18
  137. package/test/internals/reply-serialize.test.js +106 -106
  138. package/test/internals/reply.test.js +620 -585
  139. package/test/internals/{reqIdGenFactory.test.js → req-id-gen-factory.test.js} +31 -31
  140. package/test/internals/request-validate.test.js +218 -221
  141. package/test/internals/request.test.js +225 -107
  142. package/test/internals/server.test.js +15 -12
  143. package/test/internals/validation.test.js +35 -36
  144. package/test/{keepAliveTimeout.test.js → keep-alive-timeout.test.js} +9 -10
  145. package/test/listen.5.test.js +9 -9
  146. package/test/{maxRequestsPerSocket.test.js → max-requests-per-socket.test.js} +30 -30
  147. package/test/middleware.test.js +4 -5
  148. package/test/noop-set.test.js +5 -5
  149. package/test/post-empty-body.test.js +18 -11
  150. package/test/pretty-print.test.js +59 -49
  151. package/test/proto-poisoning.test.js +42 -37
  152. package/test/reply-code.test.js +34 -32
  153. package/test/{reply-earlyHints.test.js → reply-early-hints.test.js} +21 -19
  154. package/test/request-error.test.js +122 -0
  155. package/test/request-header-host.test.js +339 -0
  156. package/test/request-id.test.js +31 -25
  157. package/test/{requestTimeout.test.js → request-timeout.test.js} +11 -11
  158. package/test/route.1.test.js +79 -72
  159. package/test/route.2.test.js +17 -16
  160. package/test/route.3.test.js +32 -27
  161. package/test/route.4.test.js +21 -25
  162. package/test/route.5.test.js +45 -64
  163. package/test/route.6.test.js +70 -89
  164. package/test/route.7.test.js +61 -65
  165. package/test/route.8.test.js +80 -18
  166. package/test/router-options.test.js +80 -77
  167. package/test/same-shape.test.js +5 -5
  168. package/test/schema-examples.test.js +72 -38
  169. package/test/serialize-response.test.js +9 -10
  170. package/test/server.test.js +75 -78
  171. package/test/set-error-handler.test.js +2 -3
  172. package/test/stream-serializers.test.js +10 -7
  173. package/test/sync-routes.test.js +18 -18
  174. package/test/test-reporter.mjs +68 -0
  175. package/test/trust-proxy.test.js +51 -45
  176. package/test/type-provider.test.js +8 -6
  177. package/test/types/content-type-parser.test-d.ts +1 -1
  178. package/test/types/fastify.test-d.ts +16 -4
  179. package/test/types/hooks.test-d.ts +2 -1
  180. package/test/types/instance.test-d.ts +13 -13
  181. package/test/types/logger.test-d.ts +2 -2
  182. package/test/types/plugin.test-d.ts +17 -9
  183. package/test/types/register.test-d.ts +22 -6
  184. package/test/types/reply.test-d.ts +1 -1
  185. package/test/types/route.test-d.ts +34 -4
  186. package/test/types/serverFactory.test-d.ts +1 -1
  187. package/test/types/type-provider.test-d.ts +1 -1
  188. package/test/url-rewriting.test.js +35 -38
  189. package/test/{useSemicolonDelimiter.test.js → use-semicolon-delimiter.test.js} +30 -30
  190. package/test/validation-error-handling.test.js +259 -285
  191. package/test/versioned-routes.test.js +126 -113
  192. package/test/web-api.test.js +48 -37
  193. package/test/{wrapThenable.test.js → wrap-thenable.test.js} +10 -9
  194. package/types/hooks.d.ts +2 -1
  195. package/types/instance.d.ts +9 -2
  196. package/types/register.d.ts +12 -3
  197. package/types/reply.d.ts +1 -1
  198. package/types/request.d.ts +2 -6
  199. package/types/serverFactory.d.ts +3 -3
  200. package/types/utils.d.ts +13 -5
  201. package/test/types/import.js +0 -2
@@ -363,6 +363,128 @@ test('request.routeOptions should be immutable', t => {
363
363
  })
364
364
  })
365
365
 
366
+ test('request.routeOptions.method is an uppercase string /1', t => {
367
+ t.plan(4)
368
+ const fastify = Fastify()
369
+ const handler = function (req, res) {
370
+ t.equal('POST', req.routeOptions.method)
371
+ res.send({})
372
+ }
373
+
374
+ fastify.post('/', {
375
+ bodyLimit: 1000,
376
+ handler
377
+ })
378
+ fastify.listen({ port: 0 }, function (err) {
379
+ t.error(err)
380
+ t.teardown(() => { fastify.close() })
381
+
382
+ sget({
383
+ method: 'POST',
384
+ url: 'http://localhost:' + fastify.server.address().port,
385
+ headers: { 'Content-Type': 'application/json' },
386
+ body: [],
387
+ json: true
388
+ }, (err, response, body) => {
389
+ t.error(err)
390
+ t.equal(response.statusCode, 200)
391
+ })
392
+ })
393
+ })
394
+
395
+ test('request.routeOptions.method is an uppercase string /2', t => {
396
+ t.plan(4)
397
+ const fastify = Fastify()
398
+ const handler = function (req, res) {
399
+ t.equal('POST', req.routeOptions.method)
400
+ res.send({})
401
+ }
402
+
403
+ fastify.route({
404
+ url: '/',
405
+ method: 'POST',
406
+ bodyLimit: 1000,
407
+ handler
408
+ })
409
+ fastify.listen({ port: 0 }, function (err) {
410
+ t.error(err)
411
+ t.teardown(() => { fastify.close() })
412
+
413
+ sget({
414
+ method: 'POST',
415
+ url: 'http://localhost:' + fastify.server.address().port,
416
+ headers: { 'Content-Type': 'application/json' },
417
+ body: [],
418
+ json: true
419
+ }, (err, response, body) => {
420
+ t.error(err)
421
+ t.equal(response.statusCode, 200)
422
+ })
423
+ })
424
+ })
425
+
426
+ test('request.routeOptions.method is an uppercase string /3', t => {
427
+ t.plan(4)
428
+ const fastify = Fastify()
429
+ const handler = function (req, res) {
430
+ t.equal('POST', req.routeOptions.method)
431
+ res.send({})
432
+ }
433
+
434
+ fastify.route({
435
+ url: '/',
436
+ method: 'pOSt',
437
+ bodyLimit: 1000,
438
+ handler
439
+ })
440
+ fastify.listen({ port: 0 }, function (err) {
441
+ t.error(err)
442
+ t.teardown(() => { fastify.close() })
443
+
444
+ sget({
445
+ method: 'POST',
446
+ url: 'http://localhost:' + fastify.server.address().port,
447
+ headers: { 'Content-Type': 'application/json' },
448
+ body: [],
449
+ json: true
450
+ }, (err, response, body) => {
451
+ t.error(err)
452
+ t.equal(response.statusCode, 200)
453
+ })
454
+ })
455
+ })
456
+
457
+ test('request.routeOptions.method is an array with uppercase string', t => {
458
+ t.plan(4)
459
+ const fastify = Fastify()
460
+ const handler = function (req, res) {
461
+ t.strictSame(['POST'], req.routeOptions.method)
462
+ res.send({})
463
+ }
464
+
465
+ fastify.route({
466
+ url: '/',
467
+ method: ['pOSt'],
468
+ bodyLimit: 1000,
469
+ handler
470
+ })
471
+ fastify.listen({ port: 0 }, function (err) {
472
+ t.error(err)
473
+ t.teardown(() => { fastify.close() })
474
+
475
+ sget({
476
+ method: 'POST',
477
+ url: 'http://localhost:' + fastify.server.address().port,
478
+ headers: { 'Content-Type': 'application/json' },
479
+ body: [],
480
+ json: true
481
+ }, (err, response, body) => {
482
+ t.error(err)
483
+ t.equal(response.statusCode, 200)
484
+ })
485
+ })
486
+ })
487
+
366
488
  test('test request.routeOptions.version', t => {
367
489
  t.plan(7)
368
490
  const fastify = Fastify()
@@ -0,0 +1,339 @@
1
+ 'use strict'
2
+
3
+ const { test } = require('node:test')
4
+ const { connect } = require('node:net')
5
+ const Fastify = require('..')
6
+
7
+ // RFC9112
8
+ // https://www.rfc-editor.org/rfc/rfc9112
9
+ test('Return 400 when Host header is missing', (t, done) => {
10
+ t.plan(2)
11
+ let data = Buffer.alloc(0)
12
+ const fastify = Fastify()
13
+
14
+ t.after(() => fastify.close())
15
+
16
+ fastify.get('/', async function () {
17
+ t.assert.fail('should not reach handler')
18
+ return { ok: true }
19
+ })
20
+ fastify.listen({ port: 0 }, err => {
21
+ t.assert.ifError(err)
22
+
23
+ const socket = connect(fastify.server.address().port)
24
+ socket.write('GET / HTTP/1.1\r\n\r\n')
25
+ socket.on('data', c => (data = Buffer.concat([data, c])))
26
+ socket.on('end', () => {
27
+ t.assert.match(
28
+ data.toString('utf-8'),
29
+ /^HTTP\/1.1 400 Bad Request/
30
+ )
31
+ done()
32
+ })
33
+ })
34
+ })
35
+
36
+ test('Return 400 when Host header is missing with trust proxy', (t, done) => {
37
+ t.plan(2)
38
+ let data = Buffer.alloc(0)
39
+ const fastify = Fastify({
40
+ trustProxy: true
41
+ })
42
+
43
+ t.after(() => fastify.close())
44
+
45
+ fastify.get('/', async function () {
46
+ t.assert.fail('should not reach handler')
47
+ return { ok: true }
48
+ })
49
+ fastify.listen({ port: 0 }, err => {
50
+ t.assert.ifError(err)
51
+
52
+ const socket = connect(fastify.server.address().port)
53
+ socket.write('GET / HTTP/1.1\r\n\r\n')
54
+ socket.on('data', c => (data = Buffer.concat([data, c])))
55
+ socket.on('end', () => {
56
+ t.assert.match(
57
+ data.toString('utf-8'),
58
+ /^HTTP\/1.1 400 Bad Request/
59
+ )
60
+ done()
61
+ })
62
+ })
63
+ })
64
+
65
+ test('Return 200 when Host header is empty', (t, done) => {
66
+ t.plan(5)
67
+ let data = Buffer.alloc(0)
68
+ const fastify = Fastify({
69
+ keepAliveTimeout: 10
70
+ })
71
+
72
+ t.after(() => fastify.close())
73
+
74
+ fastify.get('/', async function (request) {
75
+ t.assert.strictEqual(request.host, '')
76
+ t.assert.strictEqual(request.hostname, '')
77
+ t.assert.strictEqual(request.port, null)
78
+ return { ok: true }
79
+ })
80
+ fastify.listen({ port: 0 }, err => {
81
+ t.assert.ifError(err)
82
+
83
+ const socket = connect(fastify.server.address().port)
84
+ socket.write('GET / HTTP/1.1\r\nHost:\r\n\r\n')
85
+ socket.on('data', c => (data = Buffer.concat([data, c])))
86
+ socket.on('end', () => {
87
+ t.assert.match(
88
+ data.toString('utf-8'),
89
+ /^HTTP\/1.1 200 OK/
90
+ )
91
+ done()
92
+ })
93
+ })
94
+ })
95
+
96
+ test('Return 200 when Host header is empty with trust proxy', (t, done) => {
97
+ t.plan(5)
98
+ let data = Buffer.alloc(0)
99
+ const fastify = Fastify({
100
+ trustProxy: true,
101
+ keepAliveTimeout: 10
102
+ })
103
+
104
+ t.after(() => fastify.close())
105
+
106
+ fastify.get('/', async function (request) {
107
+ t.assert.strictEqual(request.host, '')
108
+ t.assert.strictEqual(request.hostname, '')
109
+ t.assert.strictEqual(request.port, null)
110
+ return { ok: true }
111
+ })
112
+ fastify.listen({ port: 0 }, err => {
113
+ t.assert.ifError(err)
114
+
115
+ const socket = connect(fastify.server.address().port)
116
+ socket.write('GET / HTTP/1.1\r\nHost:\r\n\r\n')
117
+ socket.on('data', c => (data = Buffer.concat([data, c])))
118
+ socket.on('end', () => {
119
+ t.assert.match(
120
+ data.toString('utf-8'),
121
+ /^HTTP\/1.1 200 OK/
122
+ )
123
+ done()
124
+ })
125
+ })
126
+ })
127
+
128
+ // Node.js allows exploiting RFC9112
129
+ // https://nodejs.org/docs/latest-v22.x/api/http.html#httpcreateserveroptions-requestlistener
130
+ test('Return 200 when Host header is missing and http.requireHostHeader = false', (t, done) => {
131
+ t.plan(5)
132
+ let data = Buffer.alloc(0)
133
+ const fastify = Fastify({
134
+ http: {
135
+ requireHostHeader: false
136
+ },
137
+ keepAliveTimeout: 10
138
+ })
139
+
140
+ t.after(() => fastify.close())
141
+
142
+ fastify.get('/', async function (request) {
143
+ t.assert.strictEqual(request.host, '')
144
+ t.assert.strictEqual(request.hostname, '')
145
+ t.assert.strictEqual(request.port, null)
146
+ return { ok: true }
147
+ })
148
+ fastify.listen({ port: 0 }, err => {
149
+ t.assert.ifError(err)
150
+
151
+ const socket = connect(fastify.server.address().port)
152
+ socket.write('GET / HTTP/1.1\r\n\r\n')
153
+ socket.on('data', c => (data = Buffer.concat([data, c])))
154
+ socket.on('end', () => {
155
+ t.assert.match(
156
+ data.toString('utf-8'),
157
+ /^HTTP\/1.1 200 OK/
158
+ )
159
+ done()
160
+ })
161
+ })
162
+ })
163
+
164
+ test('Return 200 when Host header is missing and http.requireHostHeader = false with trust proxy', (t, done) => {
165
+ t.plan(5)
166
+ let data = Buffer.alloc(0)
167
+ const fastify = Fastify({
168
+ http: {
169
+ requireHostHeader: false
170
+ },
171
+ trustProxy: true,
172
+ keepAliveTimeout: 10
173
+ })
174
+
175
+ t.after(() => fastify.close())
176
+
177
+ fastify.get('/', async function (request) {
178
+ t.assert.strictEqual(request.host, '')
179
+ t.assert.strictEqual(request.hostname, '')
180
+ t.assert.strictEqual(request.port, null)
181
+ return { ok: true }
182
+ })
183
+ fastify.listen({ port: 0 }, err => {
184
+ t.assert.ifError(err)
185
+
186
+ const socket = connect(fastify.server.address().port)
187
+ socket.write('GET / HTTP/1.1\r\n\r\n')
188
+ socket.on('data', c => (data = Buffer.concat([data, c])))
189
+ socket.on('end', () => {
190
+ t.assert.match(
191
+ data.toString('utf-8'),
192
+ /^HTTP\/1.1 200 OK/
193
+ )
194
+ done()
195
+ })
196
+ })
197
+ })
198
+
199
+ test('Return 200 when Host header is missing using HTTP/1.0', (t, done) => {
200
+ t.plan(5)
201
+ let data = Buffer.alloc(0)
202
+ const fastify = Fastify({
203
+ keepAliveTimeout: 10
204
+ })
205
+
206
+ t.after(() => fastify.close())
207
+
208
+ fastify.get('/', async function (request) {
209
+ t.assert.strictEqual(request.host, '')
210
+ t.assert.strictEqual(request.hostname, '')
211
+ t.assert.strictEqual(request.port, null)
212
+ return { ok: true }
213
+ })
214
+ fastify.listen({ port: 0 }, err => {
215
+ t.assert.ifError(err)
216
+
217
+ const socket = connect(fastify.server.address().port)
218
+ socket.write('GET / HTTP/1.0\r\n\r\n')
219
+ socket.on('data', c => (data = Buffer.concat([data, c])))
220
+ socket.on('end', () => {
221
+ t.assert.match(
222
+ data.toString('utf-8'),
223
+ /^HTTP\/1.1 200 OK/
224
+ )
225
+ done()
226
+ })
227
+ })
228
+ })
229
+
230
+ test('Return 200 when Host header is missing with trust proxy using HTTP/1.0', (t, done) => {
231
+ t.plan(5)
232
+ let data = Buffer.alloc(0)
233
+ const fastify = Fastify({
234
+ trustProxy: true,
235
+ keepAliveTimeout: 10
236
+ })
237
+
238
+ t.after(() => fastify.close())
239
+
240
+ fastify.get('/', async function (request) {
241
+ t.assert.strictEqual(request.host, '')
242
+ t.assert.strictEqual(request.hostname, '')
243
+ t.assert.strictEqual(request.port, null)
244
+ return { ok: true }
245
+ })
246
+ fastify.listen({ port: 0 }, err => {
247
+ t.assert.ifError(err)
248
+
249
+ const socket = connect(fastify.server.address().port)
250
+ socket.write('GET / HTTP/1.0\r\n\r\n')
251
+ socket.on('data', c => (data = Buffer.concat([data, c])))
252
+ socket.on('end', () => {
253
+ t.assert.match(
254
+ data.toString('utf-8'),
255
+ /^HTTP\/1.1 200 OK/
256
+ )
257
+ done()
258
+ })
259
+ })
260
+ })
261
+
262
+ test('Return 200 when Host header is removed by schema', (t, done) => {
263
+ t.plan(5)
264
+ let data = Buffer.alloc(0)
265
+ const fastify = Fastify({
266
+ keepAliveTimeout: 10
267
+ })
268
+
269
+ t.after(() => fastify.close())
270
+
271
+ fastify.get('/', {
272
+ schema: {
273
+ headers: {
274
+ type: 'object',
275
+ properties: {},
276
+ additionalProperties: false
277
+ }
278
+ }
279
+ }, async function (request) {
280
+ t.assert.strictEqual(request.host, '')
281
+ t.assert.strictEqual(request.hostname, '')
282
+ t.assert.strictEqual(request.port, null)
283
+ return { ok: true }
284
+ })
285
+ fastify.listen({ port: 0 }, err => {
286
+ t.assert.ifError(err)
287
+
288
+ const socket = connect(fastify.server.address().port)
289
+ socket.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
290
+ socket.on('data', c => (data = Buffer.concat([data, c])))
291
+ socket.on('end', () => {
292
+ t.assert.match(
293
+ data.toString('utf-8'),
294
+ /^HTTP\/1.1 200 OK/
295
+ )
296
+ done()
297
+ })
298
+ })
299
+ })
300
+
301
+ test('Return 200 when Host header is removed by schema with trust proxy', (t, done) => {
302
+ t.plan(5)
303
+ let data = Buffer.alloc(0)
304
+ const fastify = Fastify({
305
+ trustProxy: true,
306
+ keepAliveTimeout: 10
307
+ })
308
+
309
+ t.after(() => fastify.close())
310
+
311
+ fastify.get('/', {
312
+ schema: {
313
+ headers: {
314
+ type: 'object',
315
+ properties: {},
316
+ additionalProperties: false
317
+ }
318
+ }
319
+ }, async function (request) {
320
+ t.assert.strictEqual(request.host, '')
321
+ t.assert.strictEqual(request.hostname, '')
322
+ t.assert.strictEqual(request.port, null)
323
+ return { ok: true }
324
+ })
325
+ fastify.listen({ port: 0 }, err => {
326
+ t.assert.ifError(err)
327
+
328
+ const socket = connect(fastify.server.address().port)
329
+ socket.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
330
+ socket.on('data', c => (data = Buffer.concat([data, c])))
331
+ socket.on('end', () => {
332
+ t.assert.match(
333
+ data.toString('utf-8'),
334
+ /^HTTP\/1.1 200 OK/
335
+ )
336
+ done()
337
+ })
338
+ })
339
+ })
@@ -1,10 +1,10 @@
1
1
  'use strict'
2
2
 
3
- const t = require('tap')
3
+ const { test } = require('node:test')
4
4
  const Fastify = require('..')
5
5
  const sget = require('simple-get').concat
6
6
 
7
- t.test('The request id header key can be customized', async (t) => {
7
+ test('The request id header key can be customized', async (t) => {
8
8
  t.plan(2)
9
9
  const REQUEST_ID = '42'
10
10
 
@@ -13,16 +13,16 @@ t.test('The request id header key can be customized', async (t) => {
13
13
  })
14
14
 
15
15
  fastify.get('/', (req, reply) => {
16
- t.equal(req.id, REQUEST_ID)
16
+ t.assert.strictEqual(req.id, REQUEST_ID)
17
17
  reply.send({ id: req.id })
18
18
  })
19
19
 
20
20
  const response = await fastify.inject({ method: 'GET', url: '/', headers: { 'my-custom-request-id': REQUEST_ID } })
21
21
  const body = await response.json()
22
- t.equal(body.id, REQUEST_ID)
22
+ t.assert.strictEqual(body.id, REQUEST_ID)
23
23
  })
24
24
 
25
- t.test('The request id header key can be customized', async (t) => {
25
+ test('The request id header key can be customized', async (t) => {
26
26
  t.plan(2)
27
27
  const REQUEST_ID = '42'
28
28
 
@@ -31,16 +31,16 @@ t.test('The request id header key can be customized', async (t) => {
31
31
  })
32
32
 
33
33
  fastify.get('/', (req, reply) => {
34
- t.equal(req.id, REQUEST_ID)
34
+ t.assert.strictEqual(req.id, REQUEST_ID)
35
35
  reply.send({ id: req.id })
36
36
  })
37
37
 
38
38
  const response = await fastify.inject({ method: 'GET', url: '/', headers: { 'MY-CUSTOM-REQUEST-ID': REQUEST_ID } })
39
39
  const body = await response.json()
40
- t.equal(body.id, REQUEST_ID)
40
+ t.assert.strictEqual(body.id, REQUEST_ID)
41
41
  })
42
42
 
43
- t.test('The request id header key can be customized', (t) => {
43
+ test('The request id header key can be customized', (t, done) => {
44
44
  t.plan(4)
45
45
  const REQUEST_ID = '42'
46
46
 
@@ -49,13 +49,14 @@ t.test('The request id header key can be customized', (t) => {
49
49
  })
50
50
 
51
51
  fastify.get('/', (req, reply) => {
52
- t.equal(req.id, REQUEST_ID)
52
+ t.assert.strictEqual(req.id, REQUEST_ID)
53
53
  reply.send({ id: req.id })
54
54
  })
55
55
 
56
+ t.after(() => fastify.close())
57
+
56
58
  fastify.listen({ port: 0 }, (err, address) => {
57
- t.error(err)
58
- t.teardown(() => fastify.close())
59
+ t.assert.ifError(err)
59
60
 
60
61
  sget({
61
62
  method: 'GET',
@@ -64,13 +65,14 @@ t.test('The request id header key can be customized', (t) => {
64
65
  'my-custom-request-id': REQUEST_ID
65
66
  }
66
67
  }, (err, response, body) => {
67
- t.error(err)
68
- t.equal(body.toString(), `{"id":"${REQUEST_ID}"}`)
68
+ t.assert.ifError(err)
69
+ t.assert.strictEqual(body.toString(), `{"id":"${REQUEST_ID}"}`)
70
+ done()
69
71
  })
70
72
  })
71
73
  })
72
74
 
73
- t.test('The request id header key can be customized', (t) => {
75
+ test('The request id header key can be customized', (t, done) => {
74
76
  t.plan(4)
75
77
  const REQUEST_ID = '42'
76
78
 
@@ -79,13 +81,14 @@ t.test('The request id header key can be customized', (t) => {
79
81
  })
80
82
 
81
83
  fastify.get('/', (req, reply) => {
82
- t.equal(req.id, REQUEST_ID)
84
+ t.assert.strictEqual(req.id, REQUEST_ID)
83
85
  reply.send({ id: req.id })
84
86
  })
85
87
 
88
+ t.after(() => fastify.close())
89
+
86
90
  fastify.listen({ port: 0 }, (err, address) => {
87
- t.error(err)
88
- t.teardown(() => fastify.close())
91
+ t.assert.ifError(err)
89
92
 
90
93
  sget({
91
94
  method: 'GET',
@@ -94,13 +97,14 @@ t.test('The request id header key can be customized', (t) => {
94
97
  'MY-CUSTOM-REQUEST-ID': REQUEST_ID
95
98
  }
96
99
  }, (err, response, body) => {
97
- t.error(err)
98
- t.equal(body.toString(), `{"id":"${REQUEST_ID}"}`)
100
+ t.assert.ifError(err)
101
+ t.assert.strictEqual(body.toString(), `{"id":"${REQUEST_ID}"}`)
102
+ done()
99
103
  })
100
104
  })
101
105
  })
102
106
 
103
- t.test('The request id header key can be customized', (t) => {
107
+ test('The request id header key can be customized', (t, done) => {
104
108
  t.plan(4)
105
109
  const REQUEST_ID = '42'
106
110
 
@@ -109,13 +113,14 @@ t.test('The request id header key can be customized', (t) => {
109
113
  })
110
114
 
111
115
  fastify.get('/', (req, reply) => {
112
- t.equal(req.id, REQUEST_ID)
116
+ t.assert.strictEqual(req.id, REQUEST_ID)
113
117
  reply.send({ id: req.id })
114
118
  })
115
119
 
120
+ t.after(() => fastify.close())
121
+
116
122
  fastify.listen({ port: 0 }, (err, address) => {
117
- t.error(err)
118
- t.teardown(() => fastify.close())
123
+ t.assert.ifError(err)
119
124
 
120
125
  sget({
121
126
  method: 'GET',
@@ -124,8 +129,9 @@ t.test('The request id header key can be customized', (t) => {
124
129
  'MY-CUSTOM-REQUEST-ID': REQUEST_ID
125
130
  }
126
131
  }, (err, response, body) => {
127
- t.error(err)
128
- t.equal(body.toString(), `{"id":"${REQUEST_ID}"}`)
132
+ t.assert.ifError(err)
133
+ t.assert.strictEqual(body.toString(), `{"id":"${REQUEST_ID}"}`)
134
+ done()
129
135
  })
130
136
  })
131
137
  })
@@ -1,31 +1,31 @@
1
1
  'use strict'
2
2
 
3
3
  const http = require('node:http')
4
- const { test } = require('tap')
5
- const Fastify = require('../fastify')
4
+ const { test } = require('node:test')
5
+ const Fastify = require('..')
6
6
 
7
7
  test('requestTimeout passed to server', t => {
8
8
  t.plan(5)
9
9
 
10
10
  try {
11
11
  Fastify({ requestTimeout: 500.1 })
12
- t.fail('option must be an integer')
12
+ t.assert.fail('option must be an integer')
13
13
  } catch (err) {
14
- t.ok(err)
14
+ t.assert.ok(err)
15
15
  }
16
16
 
17
17
  try {
18
18
  Fastify({ requestTimeout: [] })
19
- t.fail('option must be an integer')
19
+ t.assert.fail('option must be an integer')
20
20
  } catch (err) {
21
- t.ok(err)
21
+ t.assert.ok(err)
22
22
  }
23
23
 
24
24
  const httpServer = Fastify({ requestTimeout: 1000 }).server
25
- t.equal(httpServer.requestTimeout, 1000)
25
+ t.assert.strictEqual(httpServer.requestTimeout, 1000)
26
26
 
27
27
  const httpsServer = Fastify({ requestTimeout: 1000, https: true }).server
28
- t.equal(httpsServer.requestTimeout, 1000)
28
+ t.assert.strictEqual(httpsServer.requestTimeout, 1000)
29
29
 
30
30
  const serverFactory = (handler, _) => {
31
31
  const server = http.createServer((req, res) => {
@@ -35,19 +35,19 @@ test('requestTimeout passed to server', t => {
35
35
  return server
36
36
  }
37
37
  const customServer = Fastify({ requestTimeout: 4000, serverFactory }).server
38
- t.equal(customServer.requestTimeout, 5000)
38
+ t.assert.strictEqual(customServer.requestTimeout, 5000)
39
39
  })
40
40
 
41
41
  test('requestTimeout should be set', async (t) => {
42
42
  t.plan(1)
43
43
 
44
44
  const initialConfig = Fastify({ requestTimeout: 5000 }).initialConfig
45
- t.same(initialConfig.requestTimeout, 5000)
45
+ t.assert.strictEqual(initialConfig.requestTimeout, 5000)
46
46
  })
47
47
 
48
48
  test('requestTimeout should 0', async (t) => {
49
49
  t.plan(1)
50
50
 
51
51
  const initialConfig = Fastify().initialConfig
52
- t.same(initialConfig.requestTimeout, 0)
52
+ t.assert.strictEqual(initialConfig.requestTimeout, 0)
53
53
  })