fastify 4.28.0 → 5.0.0-alpha.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.
- package/.markdownlint-cli2.yaml +1 -1
- package/.tap/processinfo/{86b9786f-4a98-43b8-882a-5f936b876f08.json → 09002e93-10ad-430c-bc86-c0576928b0ed.json} +60 -60
- package/.tap/processinfo/{70168912-9bb2-4334-bb89-041f1764cddf.json → ee66c5ab-635d-48b5-8be6-3dc3ceea5bfc.json} +71 -71
- package/.tap/test-results/test/build/error-serializer.test.js.tap +6 -2
- package/.tap/test-results/test/build/version.test.js.tap +1 -1
- package/.taprc +4 -8
- package/README.md +3 -6
- package/build/build-error-serializer.js +4 -1
- package/build/build-validation.js +5 -4
- package/docs/Guides/Database.md +1 -1
- package/docs/Guides/Delay-Accepting-Requests.md +3 -3
- package/docs/Guides/Ecosystem.md +2 -0
- package/docs/Guides/Migration-Guide-V5.md +20 -0
- package/docs/Guides/Write-Type-Provider.md +4 -2
- package/docs/Reference/ContentTypeParser.md +30 -1
- package/docs/Reference/Decorators.md +42 -16
- package/docs/Reference/Errors.md +10 -2
- package/docs/Reference/Hooks.md +48 -14
- package/docs/Reference/Logging.md +5 -5
- package/docs/Reference/Reply.md +23 -18
- package/docs/Reference/Request.md +5 -1
- package/docs/Reference/Routes.md +24 -28
- package/docs/Reference/Server.md +14 -53
- package/docs/Reference/Type-Providers.md +21 -26
- package/docs/Reference/TypeScript.md +46 -29
- package/docs/Reference/Warnings.md +0 -8
- package/eslint.config.js +27 -0
- package/examples/typescript-server.ts +14 -14
- package/fastify.d.ts +15 -14
- package/fastify.js +41 -15
- package/lib/configValidator.js +94 -76
- package/lib/contentTypeParser.js +54 -88
- package/lib/decorate.js +3 -7
- package/lib/error-serializer.js +2 -1
- package/lib/errors.js +31 -6
- package/lib/handleRequest.js +70 -39
- package/lib/httpMethods.js +34 -18
- package/lib/logger.js +24 -6
- package/lib/pluginUtils.js +5 -5
- package/lib/reply.js +7 -10
- package/lib/request.js +37 -19
- package/lib/route.js +6 -34
- package/lib/server.js +62 -123
- package/lib/warnings.js +24 -29
- package/lib/wrapThenable.js +46 -22
- package/package.json +38 -58
- package/test/404s.test.js +8 -12
- package/test/async-await.test.js +46 -2
- package/test/build/error-serializer.test.js +4 -2
- package/test/check.test.js +225 -0
- package/test/close-pipelining.test.js +2 -41
- package/test/close.test.js +1 -41
- package/test/content-parser.test.js +69 -117
- package/test/custom-parser.1.test.js +40 -1
- package/test/decorator-namespace.test._js_ +31 -0
- package/test/decorator.test.js +92 -43
- package/test/delete.test.js +21 -1
- package/test/diagnostics-channel/404.test.js +57 -0
- package/test/diagnostics-channel/async-delay-request.test.js +74 -0
- package/test/diagnostics-channel/async-request.test.js +72 -0
- package/test/diagnostics-channel/error-before-handler.test.js +36 -0
- package/test/diagnostics-channel/error-request.test.js +61 -0
- package/test/diagnostics-channel/error-status.test.js +39 -0
- package/test/{diagnostics-channel.test.js → diagnostics-channel/init.test.js} +6 -16
- package/test/diagnostics-channel/sync-delay-request.test.js +58 -0
- package/test/diagnostics-channel/sync-request-reply.test.js +58 -0
- package/test/diagnostics-channel/sync-request.test.js +61 -0
- package/test/encapsulated-error-handler.test.js +201 -14
- package/test/esm/index.test.js +2 -12
- package/test/findRoute.test.js +16 -0
- package/test/genReqId.test.js +9 -0
- package/test/get.test.js +28 -0
- package/test/has-route.test.js +1 -1
- package/test/helper.js +1 -5
- package/test/hooks.test.js +0 -4
- package/test/http2/constraint.test.js +22 -1
- package/test/http2/plain.test.js +21 -6
- package/test/http2/secure.test.js +12 -1
- package/test/https/https.test.js +57 -0
- package/test/inject.test.js +1 -2
- package/test/internals/decorator.test.js +0 -2
- package/test/internals/errors.test.js +57 -17
- package/test/internals/handleRequest.test.js +5 -1
- package/test/internals/initialConfig.test.js +5 -5
- package/test/internals/logger.test.js +31 -2
- package/test/internals/reply.test.js +6 -78
- package/test/internals/request.test.js +13 -11
- package/test/listen.1.test.js +5 -15
- package/test/listen.5.test.js +88 -0
- package/test/logger/instantiation.test.js +8 -8
- package/test/logger/logging.test.js +4 -4
- package/test/logger/options.test.js +102 -21
- package/test/logger/response.test.js +6 -6
- package/test/maxRequestsPerSocket.test.js +2 -5
- package/test/method-missing.test.js +24 -0
- package/test/plugin.1.test.js +2 -4
- package/test/plugin.2.test.js +0 -2
- package/test/plugin.3.test.js +0 -2
- package/test/plugin.4.test.js +92 -56
- package/test/register.test.js +2 -4
- package/test/reply-earlyHints.test.js +98 -0
- package/test/reply-error.test.js +0 -2
- package/test/route-hooks.test.js +0 -1
- package/test/route-shorthand.test.js +60 -0
- package/test/schema-special-usage.test.js +1 -1
- package/test/server.test.js +17 -2
- package/test/stream.2.test.js +1 -1
- package/test/stream.4.test.js +0 -42
- package/test/stream.5.test.js +2 -2
- package/test/trust-proxy.test.js +33 -27
- package/test/types/errors.test-d.ts +0 -2
- package/test/types/fastify.test-d.ts +14 -12
- package/test/types/hooks.test-d.ts +1 -0
- package/test/types/import.ts +1 -0
- package/test/types/instance.test-d.ts +10 -51
- package/test/types/logger.test-d.ts +43 -6
- package/test/types/plugin.test-d.ts +5 -2
- package/test/types/register.test-d.ts +2 -2
- package/test/types/reply.test-d.ts +13 -12
- package/test/types/request.test-d.ts +19 -8
- package/test/types/route.test-d.ts +30 -2
- package/test/types/schema.test-d.ts +2 -2
- package/test/types/serverFactory.test-d.ts +1 -1
- package/test/types/type-provider.test-d.ts +59 -12
- package/test/types/using.test-d.ts +4 -1
- package/test/url-rewriting.test.js +3 -2
- package/test/useSemicolonDelimiter.test.js +3 -6
- package/test/versioned-routes.test.js +1 -1
- package/test/web-api.test.js +0 -6
- package/types/content-type-parser.d.ts +3 -3
- package/types/context.d.ts +0 -1
- package/types/errors.d.ts +1 -0
- package/types/hooks.d.ts +6 -6
- package/types/instance.d.ts +28 -41
- package/types/logger.d.ts +3 -3
- package/types/plugin.d.ts +3 -3
- package/types/reply.d.ts +9 -12
- package/types/request.d.ts +5 -3
- package/types/route.d.ts +31 -31
- package/types/schema.d.ts +3 -3
- package/types/serverFactory.d.ts +2 -2
- package/types/type-provider.d.ts +22 -12
- package/types/utils.d.ts +18 -23
- package/.c8rc.json +0 -8
- package/.eslintrc +0 -4
- package/.tap/processinfo/029eb7a1-1942-40bc-98e2-cef3b7a14b5e.json +0 -268
- package/.tap/processinfo/03c196c6-01c3-4268-a9b5-298dff18a873.json +0 -269
- package/.tap/processinfo/04bbabba-8611-4908-9092-dfa9fcc13327.json +0 -268
- package/.tap/processinfo/05d8a743-3edf-4e2d-ae5a-dc99d0855ba5.json +0 -272
- package/.tap/processinfo/07718963-36a8-4d87-82ad-366c877a5247.json +0 -268
- package/.tap/processinfo/08fe3bde-5814-4308-9158-cdf1e47391b7.json +0 -268
- package/.tap/processinfo/0a3e3fb0-eabf-4532-ae80-20434da22678.json +0 -268
- package/.tap/processinfo/0caf2a75-4b3a-46c4-9b41-c7e450e5e15f.json +0 -268
- package/.tap/processinfo/0cf35d52-e5b2-4884-bcf0-b0ab3017b689.json +0 -268
- package/.tap/processinfo/0e666134-5013-4ecd-9ee6-59b22716c39c.json +0 -268
- package/.tap/processinfo/1087b811-4ec4-4f91-92b4-a78a51a437de.json +0 -268
- package/.tap/processinfo/13709ed3-b68c-42cf-8472-b0c4b8a89d2b.json +0 -268
- package/.tap/processinfo/13ac2f18-d0e0-439f-bc86-2ff0119af857.json +0 -268
- package/.tap/processinfo/13e47e0e-f6e8-4381-8a42-923b661f4a4f.json +0 -268
- package/.tap/processinfo/143f7d43-b8e8-4666-b482-f28fb37160ee.json +0 -268
- package/.tap/processinfo/14f3801d-03ab-4db3-9df5-c5d47e0a8cf0.json +0 -270
- package/.tap/processinfo/15a07dad-4bcd-442c-95e0-30c31f2b9818.json +0 -273
- package/.tap/processinfo/191ad3ad-04d8-4fb9-b119-ad2811f9b925.json +0 -243
- package/.tap/processinfo/1b25d54b-62d3-44cd-b581-31e705522fae.json +0 -268
- package/.tap/processinfo/1b7cb260-f04b-4135-a4fe-093081c4706f.json +0 -268
- package/.tap/processinfo/1e395d63-4815-4c77-aa47-df3709cc0ef9.json +0 -268
- package/.tap/processinfo/1e7f6a54-3abf-4771-863a-585cba110aec.json +0 -268
- package/.tap/processinfo/21a15e1d-0b41-47d8-b03d-0ba130969034.json +0 -244
- package/.tap/processinfo/21e02016-9ecd-4983-8417-9c74d224644f.json +0 -269
- package/.tap/processinfo/2327d941-d0d5-4762-b386-02a9a27ad28e.json +0 -268
- package/.tap/processinfo/23d39204-eac9-4f57-8db4-ffa996227fbd.json +0 -268
- package/.tap/processinfo/2493875a-0ac6-4d53-993c-f44471fd0678.json +0 -268
- package/.tap/processinfo/2698669f-f1e7-4a12-a687-8d58177be2b0.json +0 -269
- package/.tap/processinfo/2862b053-0a3d-46d7-9381-ffcb06287609.json +0 -268
- package/.tap/processinfo/2ac1b8d6-ac92-40e2-a59a-7681069f487c.json +0 -268
- package/.tap/processinfo/2c75e5f7-c4ef-47e4-a1c4-105eef6c0fab.json +0 -242
- package/.tap/processinfo/2e2c45cd-718b-4e5a-bf88-f801630f2803.json +0 -268
- package/.tap/processinfo/2f9ca478-3e03-4cce-a0bc-fcdc86d7c316.json +0 -268
- package/.tap/processinfo/30e3117f-fb74-456f-8f02-527e9eb9fcc3.json +0 -268
- package/.tap/processinfo/332be679-63c7-4b49-8b87-ef55995ada2d.json +0 -268
- package/.tap/processinfo/37c36f95-07f9-4ef0-8ab4-9e107d51b605.json +0 -269
- package/.tap/processinfo/3874eae2-f3db-44ef-9a9f-c8169d4b2b76.json +0 -268
- package/.tap/processinfo/38a7c3da-a411-41d0-8993-9deefd23500d.json +0 -268
- package/.tap/processinfo/3a7b6dbd-e153-4ce5-b557-21fb82009983.json +0 -269
- package/.tap/processinfo/3c6731ec-936d-470f-b7b0-0c87b54be051.json +0 -268
- package/.tap/processinfo/3c850ea9-4ef0-4044-a3fd-fbadfa9d543e.json +0 -268
- package/.tap/processinfo/3e4e15e0-a325-46f0-be57-5fd374560b7a.json +0 -269
- package/.tap/processinfo/3ed868e0-887c-402a-9f22-b1fdb74b4da0.json +0 -268
- package/.tap/processinfo/405498d7-5854-4ce1-a7dc-06920932f26d.json +0 -268
- package/.tap/processinfo/40b7eb19-ae35-4490-8a11-eb91a573c590.json +0 -268
- package/.tap/processinfo/40bb1260-d856-4248-8939-a0a05e322041.json +0 -268
- package/.tap/processinfo/41252e0b-7f69-44cc-b356-dd94bcbfdb29.json +0 -268
- package/.tap/processinfo/418fa710-e2fd-4508-b533-c179958da464.json +0 -269
- package/.tap/processinfo/433ef009-63aa-48fe-8e5d-c725228fa2fc.json +0 -268
- package/.tap/processinfo/44bf577c-9c01-4197-bd29-2e1ae888c4d4.json +0 -268
- package/.tap/processinfo/458fb7f2-20b9-48a2-8853-403c9851f605.json +0 -268
- package/.tap/processinfo/46b9892b-bb23-4b86-b0fa-9297f08c611a.json +0 -268
- package/.tap/processinfo/46bd9aaf-6cf3-4bd5-b90d-e136a7299a8e.json +0 -268
- package/.tap/processinfo/4779aa5f-e57a-4fcc-87e2-7d0bd4fca27f.json +0 -268
- package/.tap/processinfo/47b73f4b-ab31-49e1-97fd-8436dbe4bdf3.json +0 -269
- package/.tap/processinfo/49dba52e-e0c9-445d-8e9d-6d9ebe3ce6c4.json +0 -268
- package/.tap/processinfo/4b1dbc61-4e65-4c56-9784-2036f369038a.json +0 -268
- package/.tap/processinfo/4b6f0b40-43ef-4668-83a0-e07e28509df5.json +0 -268
- package/.tap/processinfo/4c236f70-f532-460b-8f7a-dd973301d493.json +0 -268
- package/.tap/processinfo/4d92b707-a268-48b8-885b-004d3a288c41.json +0 -269
- package/.tap/processinfo/4ff10bae-7c97-4c0a-b712-6c0d2f8c0e8e.json +0 -270
- package/.tap/processinfo/50f95bd5-ae12-4d83-99f4-ae9b0690c6a8.json +0 -268
- package/.tap/processinfo/557e4a49-d99c-4a63-b2f2-f33d897ab874.json +0 -268
- package/.tap/processinfo/589fd21a-8319-4abf-8cf7-82cb4a463a4b.json +0 -269
- package/.tap/processinfo/5a872f3a-949f-40be-8004-d739d034255c.json +0 -272
- package/.tap/processinfo/5abc301a-23da-424d-891e-3afbaff9156c.json +0 -269
- package/.tap/processinfo/5c31614c-a766-4837-ab59-dd6977166f72.json +0 -253
- package/.tap/processinfo/5d1e90c8-d819-4901-b022-f9ea4cd81978.json +0 -268
- package/.tap/processinfo/5d283e67-f31d-4fa8-a559-a1d8e82ee046.json +0 -269
- package/.tap/processinfo/5df505bc-6a4b-4c41-822f-51e2d7111de8.json +0 -268
- package/.tap/processinfo/5eaf64a2-fbfd-40e7-b391-c30f744b2bf1.json +0 -269
- package/.tap/processinfo/5ef5ede0-6436-4938-8401-d32ad4bffd5d.json +0 -268
- package/.tap/processinfo/606f05c0-8293-41db-bc92-eea82123697f.json +0 -269
- package/.tap/processinfo/6446806d-6cab-4c1d-a9ed-6bccaf3c4ea9.json +0 -268
- package/.tap/processinfo/64da7e08-925d-444d-98de-6568c6115d8d.json +0 -269
- package/.tap/processinfo/6917da6d-d2dc-466a-a893-7fb7412dde96.json +0 -268
- package/.tap/processinfo/69bbeee0-c398-4ccf-98b3-fb625a63bab4.json +0 -268
- package/.tap/processinfo/6da6ea8f-3370-4703-b230-90159531f766.json +0 -268
- package/.tap/processinfo/6ecffe1f-3016-4c11-9294-b488baced99f.json +0 -268
- package/.tap/processinfo/6f23f41f-ccbd-48cb-9ab6-311db0cfb65c.json +0 -270
- package/.tap/processinfo/713a674e-40e1-46b4-866e-949d57c1a9f9.json +0 -270
- package/.tap/processinfo/730254d4-eacb-4cdf-80f4-8da22341cde5.json +0 -268
- package/.tap/processinfo/7344e559-c546-416f-8f1b-0f9fe12c6f02.json +0 -268
- package/.tap/processinfo/7556217a-0155-448f-b4d4-bec1bb0f6040.json +0 -269
- package/.tap/processinfo/7572079c-166c-4c4c-85ff-89b9430b214f.json +0 -268
- package/.tap/processinfo/7808180f-1974-47cd-bba2-2d6b8b711d65.json +0 -273
- package/.tap/processinfo/796dde83-da66-4db2-8d27-d45a3627c9c7.json +0 -268
- package/.tap/processinfo/7979819f-3723-48be-9f55-be700e689441.json +0 -270
- package/.tap/processinfo/7a664d39-d7f5-42f9-89df-15563048fab6.json +0 -268
- package/.tap/processinfo/7b047b72-01d9-4217-857c-93341651b4b3.json +0 -269
- package/.tap/processinfo/7ce41af6-7961-45ae-8c6f-b6e1c5692a48.json +0 -268
- package/.tap/processinfo/7e1de1c6-127e-463d-9357-081ee33ef5ce.json +0 -269
- package/.tap/processinfo/81ac7a7f-b0c0-4ef6-82cb-c718ea84e152.json +0 -268
- package/.tap/processinfo/851a058f-a497-4b10-a0b7-c9182d9c4d5a.json +0 -268
- package/.tap/processinfo/86502974-c245-4194-ade4-d9c6fdbb757e.json +0 -268
- package/.tap/processinfo/8a3fe726-86ab-4300-8d73-7eacbbc02a05.json +0 -268
- package/.tap/processinfo/8adf928b-c963-4ba0-9c35-606fcbd8a2aa.json +0 -272
- package/.tap/processinfo/8b31a6d8-1a33-4a27-93ca-1c5b364be068.json +0 -240
- package/.tap/processinfo/8ec12773-6b18-49a2-8e52-874c797df965.json +0 -833
- package/.tap/processinfo/8edb9502-3420-42fb-a602-e5de93be2df1.json +0 -268
- package/.tap/processinfo/8fc572e6-9828-4f98-a49c-9e081b2193c4.json +0 -242
- package/.tap/processinfo/8fee2d30-c5dd-4fae-9cf2-2ef8dd0f90de.json +0 -834
- package/.tap/processinfo/92cc0496-5f26-4370-8212-18136b972f99.json +0 -268
- package/.tap/processinfo/93a3f064-3f6e-4f49-becb-f7925f2961a9.json +0 -268
- package/.tap/processinfo/967e3697-8310-4a19-8dd5-927ac8bd6c79.json +0 -269
- package/.tap/processinfo/97225e23-9d30-4287-b3f5-72bccebec50b.json +0 -268
- package/.tap/processinfo/9a363bc6-4e65-47e8-94ca-26a9db428fb4.json +0 -268
- package/.tap/processinfo/9d2fe462-57fa-43f1-b02c-d188f15de30b.json +0 -270
- package/.tap/processinfo/a00b6cda-feb7-4b8a-8179-4c43bc29d670.json +0 -269
- package/.tap/processinfo/a017cbd5-4ac7-49e1-8c77-1bf4f6e7f2a6.json +0 -271
- package/.tap/processinfo/a1277309-1984-48f8-b60b-f5e8639736be.json +0 -271
- package/.tap/processinfo/a16bf53e-4337-48ff-88fa-67f55738e0f5.json +0 -268
- package/.tap/processinfo/a3a9848f-440e-41bb-9b0b-568bcfee0ddc.json +0 -268
- package/.tap/processinfo/a468c11f-f2f1-4e92-9ba0-6d28b6569b72.json +0 -268
- package/.tap/processinfo/a5880465-68f1-46b3-84a5-0da389d0bc67.json +0 -268
- package/.tap/processinfo/a666f394-39b4-44ad-8e74-abebf74dde3b.json +0 -270
- package/.tap/processinfo/af09d8ca-7053-4410-b514-b22c47f5979f.json +0 -268
- package/.tap/processinfo/af203309-28aa-459d-a56e-d88833695521.json +0 -268
- package/.tap/processinfo/afa2f7b6-dcd2-4d90-bf3c-54ba8b6800eb.json +0 -268
- package/.tap/processinfo/b231291d-ef14-4ff0-85f9-38a73a5408f8.json +0 -268
- package/.tap/processinfo/b3d3f2a1-a9fc-4d88-b122-fae90248cd59.json +0 -268
- package/.tap/processinfo/b834bf83-26c4-403a-8e91-eb15fe4b0b5d.json +0 -268
- package/.tap/processinfo/b8786fd7-47df-4ac1-8d6f-2d4c7623c681.json +0 -268
- package/.tap/processinfo/b9758f53-7f5a-4b03-8684-8a42ad644e5a.json +0 -268
- package/.tap/processinfo/bd194ea2-a21a-4604-b225-ee48abf1e607.json +0 -242
- package/.tap/processinfo/bd7ced53-3872-43b7-ad73-3352e50b728b.json +0 -268
- package/.tap/processinfo/be50295b-7e50-46cd-8bf1-637bf222699c.json +0 -268
- package/.tap/processinfo/bec61dd9-aa52-4e6c-8e37-5c9c10e935fd.json +0 -268
- package/.tap/processinfo/c015adf9-1d60-447e-87b5-b2031fe55bba.json +0 -268
- package/.tap/processinfo/c0666afa-7f64-45bd-97fb-145df1380157.json +0 -268
- package/.tap/processinfo/c2c0c012-c1c0-4457-84d6-dadba8396c94.json +0 -268
- package/.tap/processinfo/c3dd3ecd-737b-47ce-a917-54341c7bbed3.json +0 -268
- package/.tap/processinfo/c41ac06d-64b8-4bb3-bf56-0551f5a48f4b.json +0 -268
- package/.tap/processinfo/c4235bfb-a2aa-4271-9c6b-3ceb370219b1.json +0 -268
- package/.tap/processinfo/c4e6f24f-288c-493c-b6f0-02924aeb6758.json +0 -270
- package/.tap/processinfo/c54227bb-4a7b-40bb-bfe6-b54fe55078f3.json +0 -268
- package/.tap/processinfo/c699de91-3b0b-4466-9418-6910a3eb640a.json +0 -269
- package/.tap/processinfo/c74e2f37-451a-4577-ac18-e597fbd9a1d4.json +0 -269
- package/.tap/processinfo/c90cccec-5b4b-445f-a935-ac22859675d0.json +0 -252
- package/.tap/processinfo/c9dd6c7d-0d16-45e5-87ae-117388bf2994.json +0 -268
- package/.tap/processinfo/ca2e48fb-58c5-47fc-ad2e-263838aea42c.json +0 -272
- package/.tap/processinfo/ca87351d-c710-45c1-838a-16bccac59874.json +0 -273
- package/.tap/processinfo/cdb4a671-5776-4944-91b9-c456c58841ef.json +0 -268
- package/.tap/processinfo/cf10fdc8-6a87-447a-9e12-45f447af61f3.json +0 -244
- package/.tap/processinfo/cf3f1f08-643e-4f24-82ca-40f7a349c3d1.json +0 -268
- package/.tap/processinfo/d091172a-06a5-469b-82a9-8fefe3dd99da.json +0 -240
- package/.tap/processinfo/d1675431-61d6-45f8-a010-6e654112a00a.json +0 -272
- package/.tap/processinfo/d2d54aa2-c221-4ad4-b6b7-0c58e3c3679c.json +0 -269
- package/.tap/processinfo/d4f3c95a-ddbe-419d-bce0-dd6acceee21f.json +0 -268
- package/.tap/processinfo/d54ed8f1-43c3-478a-90d3-2c8aced723f2.json +0 -269
- package/.tap/processinfo/d6e5a2a6-4647-4d98-916c-aec4ace54a65.json +0 -268
- package/.tap/processinfo/d7280c64-45e6-4b12-affc-3ac9a5d4014a.json +0 -268
- package/.tap/processinfo/d82c8367-d825-4405-88df-07298f6ef840.json +0 -269
- package/.tap/processinfo/d8f97e53-e921-4d33-9c8d-2f7e807a9425.json +0 -268
- package/.tap/processinfo/da546a73-9714-4f8c-bdbb-e42730edbcfa.json +0 -268
- package/.tap/processinfo/da7fb7fb-1da4-49f8-a3ee-d4ea623c01a5.json +0 -268
- package/.tap/processinfo/daa6a016-4f0c-4050-923c-2022e0bb21d8.json +0 -268
- package/.tap/processinfo/db9a251d-8540-4719-b464-e7d5febd97d1.json +0 -240
- package/.tap/processinfo/dc10c603-8e58-4611-baa3-44da2578d07a.json +0 -268
- package/.tap/processinfo/dde56c1a-858c-47cc-b0bb-61279620ac17.json +0 -268
- package/.tap/processinfo/e0d9c4ea-f7c7-4c64-8ced-66dc6f0ac5d2.json +0 -271
- package/.tap/processinfo/e121454f-5dfa-4209-ba15-4c39840871f2.json +0 -831
- package/.tap/processinfo/e1f43e40-c3fe-4eb8-a713-d5910cc6b25a.json +0 -268
- package/.tap/processinfo/e4575e7a-f00e-488b-94e1-8f877b54725e.json +0 -268
- package/.tap/processinfo/e9ad667e-8603-4488-af64-449cc9532803.json +0 -268
- package/.tap/processinfo/eb26a697-e5e2-4730-aeea-bcb9c49afd4d.json +0 -268
- package/.tap/processinfo/eb29d1c3-feaf-4744-9d84-cf257e8269b0.json +0 -268
- package/.tap/processinfo/ee720c0a-ed64-4e7e-8c0a-139c7b9725d2.json +0 -268
- package/.tap/processinfo/ef88c13a-87b2-49e4-a683-7b812505cd6f.json +0 -268
- package/.tap/processinfo/f4ed6948-dac0-4128-9f86-d083b6918ea7.json +0 -268
- package/.tap/processinfo/f7544c01-8ac7-4e42-8ad5-c4d62e094d1f.json +0 -270
- package/.tap/processinfo/f7cee4b3-7bcc-4591-a628-5629b0b41c9e.json +0 -268
- package/.tap/processinfo/f9c0a1f7-c1a4-44d3-ae3f-8c1eb42cd746.json +0 -269
- package/.tap/processinfo/fc46b4da-79db-4201-af7e-34bb17f92d69.json +0 -270
- package/.tap/processinfo/fccc0056-03c4-40cb-9d0b-2db4bbe573c1.json +0 -268
- package/.tap/processinfo/fd2df572-54d7-4ce7-b7aa-a2b4b00d4127.json +0 -254
- package/.tap/processinfo/fea9377f-b473-484d-bee6-ac7f49e50937.json +0 -269
- package/.tap/processinfo/feb516dc-abda-46e6-9b42-d37adfc63366.json +0 -268
- package/.tap/processinfo/ff0fda4c-aa2e-4236-906e-fdfb6bd6632e.json +0 -269
- package/test/default-route.test.js +0 -88
- package/test/listen.deprecated.test.js +0 -229
- package/test/unsupported-httpversion.test.js +0 -31
- package/types/.eslintrc.json +0 -48
package/lib/contentTypeParser.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
const { AsyncResource } = require('node:async_hooks')
|
|
4
4
|
const { FifoMap: Fifo } = require('toad-cache')
|
|
5
|
-
const { safeParse: safeParseContentType, defaultContentType } = require('fast-content-type-parse')
|
|
6
5
|
const secureJson = require('secure-json-parse')
|
|
7
6
|
const {
|
|
8
7
|
kDefaultJsonParse,
|
|
@@ -27,6 +26,7 @@ const {
|
|
|
27
26
|
FST_ERR_CTP_EMPTY_JSON_BODY,
|
|
28
27
|
FST_ERR_CTP_INSTANCE_ALREADY_STARTED
|
|
29
28
|
} = require('./errors')
|
|
29
|
+
const { FSTSEC001 } = require('./warnings')
|
|
30
30
|
|
|
31
31
|
function ContentTypeParser (bodyLimit, onProtoPoisoning, onConstructorPoisoning) {
|
|
32
32
|
this[kDefaultJsonParse] = getDefaultJsonParser(onProtoPoisoning, onConstructorPoisoning)
|
|
@@ -34,7 +34,7 @@ function ContentTypeParser (bodyLimit, onProtoPoisoning, onConstructorPoisoning)
|
|
|
34
34
|
this.customParsers = new Map()
|
|
35
35
|
this.customParsers.set('application/json', new Parser(true, false, bodyLimit, this[kDefaultJsonParse]))
|
|
36
36
|
this.customParsers.set('text/plain', new Parser(true, false, bodyLimit, defaultPlainTextParser))
|
|
37
|
-
this.parserList = [
|
|
37
|
+
this.parserList = ['application/json', 'text/plain']
|
|
38
38
|
this.parserRegExpList = []
|
|
39
39
|
this.cache = new Fifo(100)
|
|
40
40
|
}
|
|
@@ -42,9 +42,16 @@ function ContentTypeParser (bodyLimit, onProtoPoisoning, onConstructorPoisoning)
|
|
|
42
42
|
ContentTypeParser.prototype.add = function (contentType, opts, parserFn) {
|
|
43
43
|
const contentTypeIsString = typeof contentType === 'string'
|
|
44
44
|
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
if (contentTypeIsString) {
|
|
46
|
+
contentType = contentType.trim().toLowerCase()
|
|
47
|
+
if (contentType.length === 0) throw new FST_ERR_CTP_EMPTY_TYPE()
|
|
48
|
+
} else if (!(contentType instanceof RegExp)) {
|
|
49
|
+
throw new FST_ERR_CTP_INVALID_TYPE()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (typeof parserFn !== 'function') {
|
|
53
|
+
throw new FST_ERR_CTP_INVALID_HANDLER()
|
|
54
|
+
}
|
|
48
55
|
|
|
49
56
|
if (this.existingParser(contentType)) {
|
|
50
57
|
throw new FST_ERR_CTP_ALREADY_PRESENT(contentType)
|
|
@@ -63,21 +70,29 @@ ContentTypeParser.prototype.add = function (contentType, opts, parserFn) {
|
|
|
63
70
|
parserFn
|
|
64
71
|
)
|
|
65
72
|
|
|
66
|
-
if (
|
|
73
|
+
if (contentType === '*') {
|
|
67
74
|
this.customParsers.set('', parser)
|
|
68
75
|
} else {
|
|
69
76
|
if (contentTypeIsString) {
|
|
70
|
-
this.parserList.unshift(
|
|
77
|
+
this.parserList.unshift(contentType)
|
|
78
|
+
this.customParsers.set(contentType, parser)
|
|
71
79
|
} else {
|
|
72
|
-
contentType
|
|
80
|
+
validateRegExp(contentType)
|
|
73
81
|
this.parserRegExpList.unshift(contentType)
|
|
82
|
+
this.customParsers.set(contentType.toString(), parser)
|
|
74
83
|
}
|
|
75
|
-
this.customParsers.set(contentType.toString(), parser)
|
|
76
84
|
}
|
|
77
85
|
}
|
|
78
86
|
|
|
79
87
|
ContentTypeParser.prototype.hasParser = function (contentType) {
|
|
80
|
-
|
|
88
|
+
if (typeof contentType === 'string') {
|
|
89
|
+
contentType = contentType.trim().toLowerCase()
|
|
90
|
+
} else {
|
|
91
|
+
if (!(contentType instanceof RegExp)) throw new FST_ERR_CTP_INVALID_TYPE()
|
|
92
|
+
contentType = contentType.toString()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return this.customParsers.has(contentType)
|
|
81
96
|
}
|
|
82
97
|
|
|
83
98
|
ContentTypeParser.prototype.existingParser = function (contentType) {
|
|
@@ -92,27 +107,20 @@ ContentTypeParser.prototype.existingParser = function (contentType) {
|
|
|
92
107
|
}
|
|
93
108
|
|
|
94
109
|
ContentTypeParser.prototype.getParser = function (contentType) {
|
|
95
|
-
|
|
96
|
-
return this.customParsers.get(contentType)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const parser = this.cache.get(contentType)
|
|
110
|
+
let parser = this.customParsers.get(contentType)
|
|
100
111
|
if (parser !== undefined) return parser
|
|
101
112
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
// dummyContentType always the same object
|
|
105
|
-
// we can use === for the comparison and return early
|
|
106
|
-
if (parsed === defaultContentType) {
|
|
107
|
-
return this.customParsers.get('')
|
|
108
|
-
}
|
|
113
|
+
parser = this.cache.get(contentType)
|
|
114
|
+
if (parser !== undefined) return parser
|
|
109
115
|
|
|
110
116
|
// eslint-disable-next-line no-var
|
|
111
117
|
for (var i = 0; i !== this.parserList.length; ++i) {
|
|
112
118
|
const parserListItem = this.parserList[i]
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
|
|
119
|
+
if (
|
|
120
|
+
contentType.slice(0, parserListItem.length) === parserListItem &&
|
|
121
|
+
(contentType.length === parserListItem.length || contentType.charCodeAt(parserListItem.length) === 59 /* `;` */ || contentType.charCodeAt(parserListItem.length) === 32 /* ` ` */)
|
|
122
|
+
) {
|
|
123
|
+
parser = this.customParsers.get(parserListItem)
|
|
116
124
|
this.cache.set(contentType, parser)
|
|
117
125
|
return parser
|
|
118
126
|
}
|
|
@@ -121,9 +129,8 @@ ContentTypeParser.prototype.getParser = function (contentType) {
|
|
|
121
129
|
// eslint-disable-next-line no-var
|
|
122
130
|
for (var j = 0; j !== this.parserRegExpList.length; ++j) {
|
|
123
131
|
const parserRegExp = this.parserRegExpList[j]
|
|
124
|
-
if (
|
|
125
|
-
|
|
126
|
-
// we set request content-type in cache to reduce parsing of MIME type
|
|
132
|
+
if (parserRegExp.test(contentType)) {
|
|
133
|
+
parser = this.customParsers.get(parserRegExp.toString())
|
|
127
134
|
this.cache.set(contentType, parser)
|
|
128
135
|
return parser
|
|
129
136
|
}
|
|
@@ -140,13 +147,19 @@ ContentTypeParser.prototype.removeAll = function () {
|
|
|
140
147
|
}
|
|
141
148
|
|
|
142
149
|
ContentTypeParser.prototype.remove = function (contentType) {
|
|
143
|
-
|
|
150
|
+
let parsers
|
|
144
151
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
152
|
+
if (typeof contentType === 'string') {
|
|
153
|
+
contentType = contentType.trim().toLowerCase()
|
|
154
|
+
parsers = this.parserList
|
|
155
|
+
} else {
|
|
156
|
+
if (!(contentType instanceof RegExp)) throw new FST_ERR_CTP_INVALID_TYPE()
|
|
157
|
+
contentType = contentType.toString()
|
|
158
|
+
parsers = this.parserRegExpList
|
|
159
|
+
}
|
|
148
160
|
|
|
149
|
-
const
|
|
161
|
+
const removed = this.customParsers.delete(contentType)
|
|
162
|
+
const idx = parsers.findIndex(ct => ct.toString() === contentType)
|
|
150
163
|
|
|
151
164
|
if (idx > -1) {
|
|
152
165
|
parsers.splice(idx, 1)
|
|
@@ -182,7 +195,7 @@ ContentTypeParser.prototype.run = function (contentType, handler, request, reply
|
|
|
182
195
|
} else {
|
|
183
196
|
const result = parser.fn(request, request[kRequestPayloadStream], done)
|
|
184
197
|
|
|
185
|
-
if (
|
|
198
|
+
if (typeof result?.then === 'function') {
|
|
186
199
|
result.then(body => done(null, body), done)
|
|
187
200
|
}
|
|
188
201
|
}
|
|
@@ -205,9 +218,7 @@ ContentTypeParser.prototype.run = function (contentType, handler, request, reply
|
|
|
205
218
|
function rawBody (request, reply, options, parser, done) {
|
|
206
219
|
const asString = parser.asString
|
|
207
220
|
const limit = options.limit === null ? parser.bodyLimit : options.limit
|
|
208
|
-
const contentLength = request.headers['content-length']
|
|
209
|
-
? NaN
|
|
210
|
-
: Number(request.headers['content-length'])
|
|
221
|
+
const contentLength = Number(request.headers['content-length'])
|
|
211
222
|
|
|
212
223
|
if (contentLength > limit) {
|
|
213
224
|
// We must close the connection as the client is going
|
|
@@ -373,60 +384,15 @@ function removeAllContentTypeParsers () {
|
|
|
373
384
|
this[kContentTypeParser].removeAll()
|
|
374
385
|
}
|
|
375
386
|
|
|
376
|
-
function
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
// we do a full-text search
|
|
383
|
-
// reject essence content-type before checking parameters
|
|
384
|
-
if (contentType.type.indexOf(parserListItem.type) === -1) return false
|
|
385
|
-
for (const key of parserListItem.parameterKeys) {
|
|
386
|
-
// reject when missing parameters
|
|
387
|
-
if (!(key in contentType.parameters)) return false
|
|
388
|
-
// reject when parameters do not match
|
|
389
|
-
if (contentType.parameters[key] !== parserListItem.parameters[key]) return false
|
|
390
|
-
}
|
|
391
|
-
return true
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
function compareRegExpContentType (contentType, essenceMIMEType, regexp) {
|
|
396
|
-
if (regexp.isEssence) {
|
|
397
|
-
// we do essence check
|
|
398
|
-
return regexp.test(essenceMIMEType)
|
|
399
|
-
} else {
|
|
400
|
-
// when the content-type includes parameters
|
|
401
|
-
// we do a full-text match
|
|
402
|
-
return regexp.test(contentType)
|
|
387
|
+
function validateRegExp (regexp) {
|
|
388
|
+
// RegExp should either start with ^ or include ;?
|
|
389
|
+
// It can ensure the user is properly detect the essence
|
|
390
|
+
// MIME types.
|
|
391
|
+
if (regexp.source[0] !== '^' && regexp.source.includes(';?') === false) {
|
|
392
|
+
FSTSEC001(regexp.source)
|
|
403
393
|
}
|
|
404
394
|
}
|
|
405
395
|
|
|
406
|
-
function ParserListItem (contentType) {
|
|
407
|
-
this.name = contentType
|
|
408
|
-
// we pre-calculate all the needed information
|
|
409
|
-
// before content-type comparison
|
|
410
|
-
const parsed = safeParseContentType(contentType)
|
|
411
|
-
this.isEssence = contentType.indexOf(';') === -1
|
|
412
|
-
// we should not allow empty string for parser list item
|
|
413
|
-
// because it would become a match-all handler
|
|
414
|
-
if (this.isEssence === false && parsed.type === '') {
|
|
415
|
-
// handle semicolon or empty string
|
|
416
|
-
const tmp = contentType.split(';', 1)[0]
|
|
417
|
-
this.type = tmp === '' ? contentType : tmp
|
|
418
|
-
} else {
|
|
419
|
-
this.type = parsed.type
|
|
420
|
-
}
|
|
421
|
-
this.parameters = parsed.parameters
|
|
422
|
-
this.parameterKeys = Object.keys(parsed.parameters)
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
// used in ContentTypeParser.remove
|
|
426
|
-
ParserListItem.prototype.toString = function () {
|
|
427
|
-
return this.name
|
|
428
|
-
}
|
|
429
|
-
|
|
430
396
|
module.exports = ContentTypeParser
|
|
431
397
|
module.exports.helpers = {
|
|
432
398
|
buildContentTypeParser,
|
package/lib/decorate.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
/* eslint no-prototype-builtins: 0 */
|
|
4
|
-
|
|
5
3
|
const {
|
|
6
4
|
kReply,
|
|
7
5
|
kRequest,
|
|
@@ -13,11 +11,10 @@ const {
|
|
|
13
11
|
FST_ERR_DEC_ALREADY_PRESENT,
|
|
14
12
|
FST_ERR_DEC_MISSING_DEPENDENCY,
|
|
15
13
|
FST_ERR_DEC_AFTER_START,
|
|
14
|
+
FST_ERR_DEC_REFERENCE_TYPE,
|
|
16
15
|
FST_ERR_DEC_DEPENDENCY_INVALID_TYPE
|
|
17
16
|
} = require('./errors')
|
|
18
17
|
|
|
19
|
-
const { FSTDEP006 } = require('./warnings')
|
|
20
|
-
|
|
21
18
|
function decorate (instance, name, fn, dependencies) {
|
|
22
19
|
if (Object.prototype.hasOwnProperty.call(instance, name)) {
|
|
23
20
|
throw new FST_ERR_DEC_ALREADY_PRESENT(name)
|
|
@@ -58,7 +55,7 @@ function decorateConstructor (konstructor, name, fn, dependencies) {
|
|
|
58
55
|
|
|
59
56
|
function checkReferenceType (name, fn) {
|
|
60
57
|
if (typeof fn === 'object' && fn && !(typeof fn.getter === 'function' || typeof fn.setter === 'function')) {
|
|
61
|
-
|
|
58
|
+
throw new FST_ERR_DEC_REFERENCE_TYPE(name, typeof fn)
|
|
62
59
|
}
|
|
63
60
|
}
|
|
64
61
|
|
|
@@ -102,8 +99,7 @@ function checkDependencies (instance, name, deps) {
|
|
|
102
99
|
throw new FST_ERR_DEC_DEPENDENCY_INVALID_TYPE(name)
|
|
103
100
|
}
|
|
104
101
|
|
|
105
|
-
|
|
106
|
-
for (var i = 0; i !== deps.length; ++i) {
|
|
102
|
+
for (let i = 0; i !== deps.length; ++i) {
|
|
107
103
|
if (!checkExistence(instance, deps[i])) {
|
|
108
104
|
throw new FST_ERR_DEC_MISSING_DEPENDENCY(deps[i])
|
|
109
105
|
}
|
package/lib/error-serializer.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// This file is autogenerated by build/build-error-serializer.js, do not edit
|
|
2
|
-
/*
|
|
2
|
+
/* c8 ignore start */
|
|
3
3
|
|
|
4
4
|
'use strict'
|
|
5
5
|
|
|
@@ -117,3 +117,4 @@ let addComma = false
|
|
|
117
117
|
return main
|
|
118
118
|
|
|
119
119
|
}(validator, serializer)
|
|
120
|
+
/* c8 ignore stop */
|
package/lib/errors.js
CHANGED
|
@@ -151,6 +151,10 @@ const codes = {
|
|
|
151
151
|
'FST_ERR_DEC_AFTER_START',
|
|
152
152
|
"The decorator '%s' has been added after start!"
|
|
153
153
|
),
|
|
154
|
+
FST_ERR_DEC_REFERENCE_TYPE: createError(
|
|
155
|
+
'FST_ERR_DEC_REFERENCE_TYPE',
|
|
156
|
+
"The decorator '%s' of type '%s' is a reference type. Use the { getter, setter } interface instead."
|
|
157
|
+
),
|
|
154
158
|
|
|
155
159
|
/**
|
|
156
160
|
* hooks
|
|
@@ -209,6 +213,27 @@ const codes = {
|
|
|
209
213
|
TypeError
|
|
210
214
|
),
|
|
211
215
|
|
|
216
|
+
FST_ERR_LOG_INVALID_LOGGER_INSTANCE: createError(
|
|
217
|
+
'FST_ERR_LOG_INVALID_LOGGER_INSTANCE',
|
|
218
|
+
'loggerInstance only accepts a logger instance.',
|
|
219
|
+
500,
|
|
220
|
+
TypeError
|
|
221
|
+
),
|
|
222
|
+
|
|
223
|
+
FST_ERR_LOG_INVALID_LOGGER_CONFIG: createError(
|
|
224
|
+
'FST_ERR_LOG_INVALID_LOGGER_CONFIG',
|
|
225
|
+
'logger options only accepts a configuration object.',
|
|
226
|
+
500,
|
|
227
|
+
TypeError
|
|
228
|
+
),
|
|
229
|
+
|
|
230
|
+
FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED: createError(
|
|
231
|
+
'FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED',
|
|
232
|
+
'You cannot provide both logger and loggerInstance. Please provide only one.',
|
|
233
|
+
500,
|
|
234
|
+
TypeError
|
|
235
|
+
),
|
|
236
|
+
|
|
212
237
|
/**
|
|
213
238
|
* reply
|
|
214
239
|
*/
|
|
@@ -339,12 +364,6 @@ const codes = {
|
|
|
339
364
|
'Unexpected error from async constraint',
|
|
340
365
|
500
|
|
341
366
|
),
|
|
342
|
-
FST_ERR_DEFAULT_ROUTE_INVALID_TYPE: createError(
|
|
343
|
-
'FST_ERR_DEFAULT_ROUTE_INVALID_TYPE',
|
|
344
|
-
'The defaultRoute type should be a function',
|
|
345
|
-
500,
|
|
346
|
-
TypeError
|
|
347
|
-
),
|
|
348
367
|
FST_ERR_INVALID_URL: createError(
|
|
349
368
|
'FST_ERR_INVALID_URL',
|
|
350
369
|
"URL must be a string. Received '%s'",
|
|
@@ -429,6 +448,12 @@ const codes = {
|
|
|
429
448
|
'FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE',
|
|
430
449
|
"The decorator '%s'%s is not present in %s"
|
|
431
450
|
),
|
|
451
|
+
FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER: createError(
|
|
452
|
+
'FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER',
|
|
453
|
+
'The %s plugin being registered mixes async and callback styles. Async plugin should not mix async and callback style.',
|
|
454
|
+
500,
|
|
455
|
+
TypeError
|
|
456
|
+
),
|
|
432
457
|
|
|
433
458
|
/**
|
|
434
459
|
* Avvio Errors
|
package/lib/handleRequest.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { bodylessMethods, bodyMethods } = require('./httpMethods')
|
|
4
|
+
const diagnostics = require('dc-polyfill')
|
|
3
5
|
const { validate: validateSchema } = require('./validation')
|
|
4
6
|
const { preValidationHookRunner, preHandlerHookRunner } = require('./hooks')
|
|
5
7
|
const wrapThenable = require('./wrapThenable')
|
|
6
8
|
const {
|
|
7
9
|
kReplyIsError,
|
|
8
|
-
kRouteContext
|
|
10
|
+
kRouteContext,
|
|
11
|
+
kFourOhFourContext
|
|
9
12
|
} = require('./symbols')
|
|
10
13
|
|
|
14
|
+
const channels = diagnostics.tracingChannel('fastify.request.handler')
|
|
15
|
+
|
|
11
16
|
function handleRequest (err, request, reply) {
|
|
12
17
|
if (reply.sent === true) return
|
|
13
18
|
if (err != null) {
|
|
@@ -20,45 +25,37 @@ function handleRequest (err, request, reply) {
|
|
|
20
25
|
const headers = request.headers
|
|
21
26
|
const context = request[kRouteContext]
|
|
22
27
|
|
|
23
|
-
if (method
|
|
28
|
+
if (bodylessMethods.has(method)) {
|
|
24
29
|
handler(request, reply)
|
|
25
30
|
return
|
|
26
31
|
}
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
if (bodyMethods.has(method)) {
|
|
34
|
+
const contentType = headers['content-type']
|
|
35
|
+
const contentLength = headers['content-length']
|
|
36
|
+
const transferEncoding = headers['transfer-encoding']
|
|
29
37
|
|
|
30
|
-
if (method === 'POST' || method === 'PUT' || method === 'PATCH' || method === 'TRACE' || method === 'SEARCH' ||
|
|
31
|
-
method === 'PROPFIND' || method === 'PROPPATCH' || method === 'LOCK' || method === 'REPORT' || method === 'MKCALENDAR') {
|
|
32
38
|
if (contentType === undefined) {
|
|
33
39
|
if (
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
) {
|
|
40
|
+
(contentLength === undefined || contentLength === '0') &&
|
|
41
|
+
transferEncoding === undefined
|
|
42
|
+
) {
|
|
43
|
+
// Request has no body to parse
|
|
37
44
|
handler(request, reply)
|
|
38
45
|
} else {
|
|
39
46
|
context.contentTypeParser.run('', handler, request, reply)
|
|
40
47
|
}
|
|
41
48
|
} else {
|
|
49
|
+
if (contentLength === undefined && transferEncoding === undefined && method === 'OPTIONS') {
|
|
50
|
+
// OPTIONS can have a Content-Type header without a body
|
|
51
|
+
handler(request, reply)
|
|
52
|
+
return
|
|
53
|
+
}
|
|
42
54
|
context.contentTypeParser.run(contentType, handler, request, reply)
|
|
43
55
|
}
|
|
44
56
|
return
|
|
45
57
|
}
|
|
46
58
|
|
|
47
|
-
if (method === 'OPTIONS' || method === 'DELETE') {
|
|
48
|
-
if (
|
|
49
|
-
contentType !== undefined &&
|
|
50
|
-
(
|
|
51
|
-
headers['transfer-encoding'] !== undefined ||
|
|
52
|
-
headers['content-length'] !== undefined
|
|
53
|
-
)
|
|
54
|
-
) {
|
|
55
|
-
context.contentTypeParser.run(contentType, handler, request, reply)
|
|
56
|
-
} else {
|
|
57
|
-
handler(request, reply)
|
|
58
|
-
}
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
|
-
|
|
62
59
|
// Return 404 instead of 405 see https://github.com/fastify/fastify/pull/862 for discussion
|
|
63
60
|
handler(request, reply)
|
|
64
61
|
}
|
|
@@ -126,28 +123,62 @@ function validationCompleted (request, reply, validationErr) {
|
|
|
126
123
|
function preHandlerCallback (err, request, reply) {
|
|
127
124
|
if (reply.sent) return
|
|
128
125
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
126
|
+
const context = request[kRouteContext]
|
|
127
|
+
|
|
128
|
+
if (!channels.hasSubscribers || context[kFourOhFourContext] === null) {
|
|
129
|
+
preHandlerCallbackInner(err, request, reply)
|
|
130
|
+
} else {
|
|
131
|
+
const store = {
|
|
132
|
+
request,
|
|
133
|
+
reply,
|
|
134
|
+
async: false,
|
|
135
|
+
route: {
|
|
136
|
+
url: context.config.url,
|
|
137
|
+
method: context.config.method
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
channels.start.runStores(store, preHandlerCallbackInner, undefined, err, request, reply, store)
|
|
133
141
|
}
|
|
142
|
+
}
|
|
134
143
|
|
|
135
|
-
|
|
144
|
+
function preHandlerCallbackInner (err, request, reply, store) {
|
|
145
|
+
const context = request[kRouteContext]
|
|
136
146
|
|
|
137
147
|
try {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
148
|
+
if (err != null) {
|
|
149
|
+
reply[kReplyIsError] = true
|
|
150
|
+
reply.send(err)
|
|
151
|
+
if (store) {
|
|
152
|
+
store.error = err
|
|
153
|
+
channels.error.publish(store)
|
|
154
|
+
}
|
|
155
|
+
return
|
|
156
|
+
}
|
|
144
157
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
158
|
+
let result
|
|
159
|
+
|
|
160
|
+
try {
|
|
161
|
+
result = context.handler(request, reply)
|
|
162
|
+
} catch (err) {
|
|
163
|
+
if (store) {
|
|
164
|
+
store.error = err
|
|
165
|
+
channels.error.publish(store)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
reply[kReplyIsError] = true
|
|
169
|
+
reply.send(err)
|
|
170
|
+
return
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (result !== undefined) {
|
|
174
|
+
if (result !== null && typeof result.then === 'function') {
|
|
175
|
+
wrapThenable(result, reply, store)
|
|
176
|
+
} else {
|
|
177
|
+
reply.send(result)
|
|
178
|
+
}
|
|
150
179
|
}
|
|
180
|
+
} finally {
|
|
181
|
+
if (store) channels.end.publish(store)
|
|
151
182
|
}
|
|
152
183
|
}
|
|
153
184
|
|
package/lib/httpMethods.js
CHANGED
|
@@ -1,24 +1,40 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const bodylessMethods = new Set([
|
|
4
|
+
// Standard
|
|
5
|
+
'GET',
|
|
6
|
+
'HEAD',
|
|
7
|
+
'TRACE',
|
|
8
|
+
|
|
9
|
+
// WebDAV
|
|
10
|
+
'UNLOCK'
|
|
11
|
+
])
|
|
12
|
+
|
|
13
|
+
const bodyMethods = new Set([
|
|
14
|
+
// Standard
|
|
15
|
+
'DELETE',
|
|
16
|
+
'OPTIONS',
|
|
17
|
+
'PATCH',
|
|
18
|
+
'PUT',
|
|
19
|
+
'POST',
|
|
20
|
+
|
|
21
|
+
// WebDAV
|
|
22
|
+
'COPY',
|
|
23
|
+
'LOCK',
|
|
24
|
+
'MOVE',
|
|
25
|
+
'MKCOL',
|
|
26
|
+
'PROPFIND',
|
|
27
|
+
'PROPPATCH',
|
|
28
|
+
'REPORT',
|
|
29
|
+
'SEARCH',
|
|
30
|
+
'MKCALENDAR'
|
|
31
|
+
])
|
|
32
|
+
|
|
3
33
|
module.exports = {
|
|
34
|
+
bodylessMethods,
|
|
35
|
+
bodyMethods,
|
|
4
36
|
supportedMethods: [
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
'HEAD',
|
|
8
|
-
'PATCH',
|
|
9
|
-
'POST',
|
|
10
|
-
'PUT',
|
|
11
|
-
'OPTIONS',
|
|
12
|
-
'PROPFIND',
|
|
13
|
-
'PROPPATCH',
|
|
14
|
-
'MKCOL',
|
|
15
|
-
'COPY',
|
|
16
|
-
'MOVE',
|
|
17
|
-
'LOCK',
|
|
18
|
-
'UNLOCK',
|
|
19
|
-
'TRACE',
|
|
20
|
-
'SEARCH',
|
|
21
|
-
'REPORT',
|
|
22
|
-
'MKCALENDAR'
|
|
37
|
+
...bodylessMethods,
|
|
38
|
+
...bodyMethods
|
|
23
39
|
]
|
|
24
40
|
}
|
package/lib/logger.js
CHANGED
|
@@ -11,7 +11,10 @@ const pino = require('pino')
|
|
|
11
11
|
const { serializersSym } = pino.symbols
|
|
12
12
|
const {
|
|
13
13
|
FST_ERR_LOG_INVALID_DESTINATION,
|
|
14
|
-
FST_ERR_LOG_INVALID_LOGGER
|
|
14
|
+
FST_ERR_LOG_INVALID_LOGGER,
|
|
15
|
+
FST_ERR_LOG_INVALID_LOGGER_INSTANCE,
|
|
16
|
+
FST_ERR_LOG_INVALID_LOGGER_CONFIG,
|
|
17
|
+
FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED
|
|
15
18
|
} = require('./errors')
|
|
16
19
|
|
|
17
20
|
function createPinoLogger (opts) {
|
|
@@ -51,7 +54,7 @@ const serializers = {
|
|
|
51
54
|
method: req.method,
|
|
52
55
|
url: req.url,
|
|
53
56
|
version: req.headers && req.headers['accept-version'],
|
|
54
|
-
|
|
57
|
+
host: req.host,
|
|
55
58
|
remoteAddress: req.ip,
|
|
56
59
|
remotePort: req.socket ? req.socket.remotePort : undefined
|
|
57
60
|
}
|
|
@@ -70,20 +73,35 @@ function now () {
|
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
function createLogger (options) {
|
|
73
|
-
if
|
|
76
|
+
// if no logger is provided, then create a default logger
|
|
77
|
+
if (!options.loggerInstance && !options.logger) {
|
|
74
78
|
const logger = nullLogger
|
|
75
79
|
logger.child = () => logger
|
|
76
80
|
return { logger, hasLogger: false }
|
|
77
81
|
}
|
|
78
82
|
|
|
79
|
-
if (
|
|
83
|
+
if (options.logger && options.loggerInstance) {
|
|
84
|
+
throw new FST_ERR_LOG_LOGGER_AND_LOGGER_INSTANCE_PROVIDED()
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// check if the logger instance has all required properties
|
|
88
|
+
if (validateLogger(options.loggerInstance)) {
|
|
80
89
|
const logger = createPinoLogger({
|
|
81
|
-
logger: options.
|
|
82
|
-
serializers: Object.assign({}, serializers, options.
|
|
90
|
+
logger: options.loggerInstance,
|
|
91
|
+
serializers: Object.assign({}, serializers, options.loggerInstance.serializers)
|
|
83
92
|
})
|
|
84
93
|
return { logger, hasLogger: true }
|
|
85
94
|
}
|
|
86
95
|
|
|
96
|
+
// if a logger instance is passed to logger, throw an exception
|
|
97
|
+
if (validateLogger(options.logger)) {
|
|
98
|
+
throw FST_ERR_LOG_INVALID_LOGGER_CONFIG()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (options.loggerInstance) {
|
|
102
|
+
throw FST_ERR_LOG_INVALID_LOGGER_INSTANCE()
|
|
103
|
+
}
|
|
104
|
+
|
|
87
105
|
const localLoggerOptions = {}
|
|
88
106
|
if (Object.prototype.toString.call(options.logger) === '[object Object]') {
|
|
89
107
|
Reflect.ownKeys(options.logger).forEach(prop => {
|
package/lib/pluginUtils.js
CHANGED
|
@@ -9,9 +9,9 @@ const {
|
|
|
9
9
|
const { exist, existReply, existRequest } = require('./decorate')
|
|
10
10
|
const {
|
|
11
11
|
FST_ERR_PLUGIN_VERSION_MISMATCH,
|
|
12
|
-
FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE
|
|
12
|
+
FST_ERR_PLUGIN_NOT_PRESENT_IN_INSTANCE,
|
|
13
|
+
FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER
|
|
13
14
|
} = require('./errors')
|
|
14
|
-
const { FSTWRN002 } = require('./warnings.js')
|
|
15
15
|
|
|
16
16
|
function getMeta (fn) {
|
|
17
17
|
return fn[Symbol.for('plugin-meta')]
|
|
@@ -106,11 +106,11 @@ function _checkDecorators (that, instance, decorators, name) {
|
|
|
106
106
|
|
|
107
107
|
function checkVersion (fn) {
|
|
108
108
|
const meta = getMeta(fn)
|
|
109
|
-
if (
|
|
109
|
+
if (meta == null || meta?.fastify == null) return
|
|
110
110
|
|
|
111
111
|
const requiredVersion = meta.fastify
|
|
112
112
|
|
|
113
|
-
const fastifyRc = /-rc.+$/.test(this.version)
|
|
113
|
+
const fastifyRc = /-(rc|pre|alpha).+$/.test(this.version)
|
|
114
114
|
if (fastifyRc === true && semver.gt(this.version, semver.coerce(requiredVersion)) === true) {
|
|
115
115
|
// A Fastify release candidate phase is taking place. In order to reduce
|
|
116
116
|
// the effort needed to test plugins with the RC, we allow plugins targeting
|
|
@@ -138,7 +138,7 @@ function registerPluginName (fn) {
|
|
|
138
138
|
|
|
139
139
|
function checkPluginHealthiness (fn, pluginName) {
|
|
140
140
|
if (fn.constructor.name === 'AsyncFunction' && fn.length === 3) {
|
|
141
|
-
|
|
141
|
+
throw new FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER(pluginName)
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
|