fastify 4.27.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.
Files changed (328) hide show
  1. package/.markdownlint-cli2.yaml +1 -1
  2. package/.tap/processinfo/09002e93-10ad-430c-bc86-c0576928b0ed.json +241 -0
  3. package/.tap/processinfo/ee66c5ab-635d-48b5-8be6-3dc3ceea5bfc.json +268 -0
  4. package/.tap/test-results/test/404s.test.js.tap +623 -0
  5. package/.tap/test-results/test/500s.test.js.tap +64 -0
  6. package/.tap/test-results/test/allowUnsafeRegex.test.js.tap +36 -0
  7. package/.tap/test-results/test/als.test.js.tap +15 -0
  8. package/.tap/test-results/test/async-await.test.js.tap +184 -0
  9. package/.tap/test-results/test/async-dispose.test.js.tap +8 -0
  10. package/.tap/test-results/test/async_hooks.test.js.tap +10 -0
  11. package/.tap/test-results/test/bodyLimit.test.js.tap +48 -0
  12. package/.tap/test-results/test/buffer.test.js.tap +20 -0
  13. package/.tap/test-results/test/build/error-serializer.test.js.tap +12 -0
  14. package/.tap/test-results/test/build/version.test.js.tap +7 -0
  15. package/.tap/test-results/test/case-insensitive.test.js.tap +36 -0
  16. package/.tap/test-results/test/chainable.test.js.tap +17 -0
  17. package/.tap/test-results/test/check.test.js.tap +10 -0
  18. package/.tap/test-results/test/childLoggerFactory.test.js.tap +23 -0
  19. package/.tap/test-results/test/client-timeout.test.js.tap +7 -0
  20. package/.tap/test-results/test/close-pipelining.test.js.tap +15 -0
  21. package/.tap/test-results/test/close.test.js.tap +172 -0
  22. package/.tap/test-results/test/connectionTimeout.test.js.tap +12 -0
  23. package/.tap/test-results/test/constrained-routes.test.js.tap +173 -0
  24. package/.tap/test-results/test/content-length.test.js.tap +46 -0
  25. package/.tap/test-results/test/content-parser.test.js.tap +266 -0
  26. package/.tap/test-results/test/content-type.test.js.tap +14 -0
  27. package/.tap/test-results/test/context-config.test.js.tap +41 -0
  28. package/.tap/test-results/test/copy.test.js.tap +14 -0
  29. package/.tap/test-results/test/custom-http-server.test.js.tap +30 -0
  30. package/.tap/test-results/test/custom-parser-async.test.js.tap +21 -0
  31. package/.tap/test-results/test/custom-parser.0.test.js.tap +199 -0
  32. package/.tap/test-results/test/custom-parser.1.test.js.tap +90 -0
  33. package/.tap/test-results/test/custom-parser.2.test.js.tap +22 -0
  34. package/.tap/test-results/test/custom-parser.3.test.js.tap +53 -0
  35. package/.tap/test-results/test/custom-parser.4.test.js.tap +45 -0
  36. package/.tap/test-results/test/custom-parser.5.test.js.tap +41 -0
  37. package/.tap/test-results/test/custom-querystring-parser.test.js.tap +46 -0
  38. package/.tap/test-results/test/decorator.test.js.tap +465 -0
  39. package/.tap/test-results/test/delete.test.js.tap +110 -0
  40. package/.tap/test-results/test/diagnostics-channel/404.test.js.tap +15 -0
  41. package/.tap/test-results/test/diagnostics-channel/async-delay-request.test.js.tap +25 -0
  42. package/.tap/test-results/test/diagnostics-channel/async-request.test.js.tap +24 -0
  43. package/.tap/test-results/test/diagnostics-channel/error-before-handler.test.js.tap +9 -0
  44. package/.tap/test-results/test/diagnostics-channel/error-request.test.js.tap +20 -0
  45. package/.tap/test-results/test/diagnostics-channel/error-status.test.js.tap +10 -0
  46. package/.tap/test-results/test/diagnostics-channel/init.test.js.tap +14 -0
  47. package/.tap/test-results/test/diagnostics-channel/sync-delay-request.test.js.tap +16 -0
  48. package/.tap/test-results/test/diagnostics-channel/sync-request-reply.test.js.tap +16 -0
  49. package/.tap/test-results/test/diagnostics-channel/sync-request.test.js.tap +19 -0
  50. package/.tap/test-results/test/encapsulated-child-logger-factory.test.js.tap +18 -0
  51. package/.tap/test-results/test/encapsulated-error-handler.test.js.tap +243 -0
  52. package/.tap/test-results/test/esm/errorCodes.test.mjs.tap +9 -0
  53. package/.tap/test-results/test/esm/esm.test.mjs.tap +8 -0
  54. package/.tap/test-results/test/esm/index.test.js.tap +8 -0
  55. package/.tap/test-results/test/fastify-instance.test.js.tap +114 -0
  56. package/.tap/test-results/test/findRoute.test.js.tap +37 -0
  57. package/.tap/test-results/test/fluent-schema.test.js.tap +36 -0
  58. package/.tap/test-results/test/genReqId.test.js.tap +106 -0
  59. package/.tap/test-results/test/get.test.js.tap +151 -0
  60. package/.tap/test-results/test/handler-context.test.js.tap +19 -0
  61. package/.tap/test-results/test/has-route.test.js.tap +30 -0
  62. package/.tap/test-results/test/head.test.js.tap +130 -0
  63. package/.tap/test-results/test/header-overflow.test.js.tap +16 -0
  64. package/.tap/test-results/test/hooks-async.test.js.tap +286 -0
  65. package/.tap/test-results/test/hooks.on-listen.test.js.tap +311 -0
  66. package/.tap/test-results/test/hooks.on-ready.test.js.tap +151 -0
  67. package/.tap/test-results/test/hooks.test.js.tap +966 -0
  68. package/.tap/test-results/test/http2/closing.test.js.tap +35 -0
  69. package/.tap/test-results/test/http2/constraint.test.js.tap +32 -0
  70. package/.tap/test-results/test/http2/head.test.js.tap +9 -0
  71. package/.tap/test-results/test/http2/missing-http2-module.test.js.tap +8 -0
  72. package/.tap/test-results/test/http2/plain.test.js.tap +22 -0
  73. package/.tap/test-results/test/http2/secure-with-fallback.test.js.tap +40 -0
  74. package/.tap/test-results/test/http2/secure.test.js.tap +27 -0
  75. package/.tap/test-results/test/http2/unknown-http-method.test.js.tap +9 -0
  76. package/.tap/test-results/test/https/custom-https-server.test.js.tap +10 -0
  77. package/.tap/test-results/test/https/https.test.js.tap +45 -0
  78. package/.tap/test-results/test/imports.test.js.tap +14 -0
  79. package/.tap/test-results/test/inject.test.js.tap +165 -0
  80. package/.tap/test-results/test/internals/all.test.js.tap +42 -0
  81. package/.tap/test-results/test/internals/contentTypeParser.test.js.tap +14 -0
  82. package/.tap/test-results/test/internals/context.test.js.tap +14 -0
  83. package/.tap/test-results/test/internals/decorator.test.js.tap +51 -0
  84. package/.tap/test-results/test/internals/errors.test.js.tap +1212 -0
  85. package/.tap/test-results/test/internals/handleRequest.test.js.tap +69 -0
  86. package/.tap/test-results/test/internals/hookRunner.test.js.tap +143 -0
  87. package/.tap/test-results/test/internals/hooks.test.js.tap +45 -0
  88. package/.tap/test-results/test/internals/initialConfig.test.js.tap +125 -0
  89. package/.tap/test-results/test/internals/logger.test.js.tap +71 -0
  90. package/.tap/test-results/test/internals/plugin.test.js.tap +48 -0
  91. package/.tap/test-results/test/internals/reply-serialize.test.js.tap +166 -0
  92. package/.tap/test-results/test/internals/reply.test.js.tap +688 -0
  93. package/.tap/test-results/test/internals/reqIdGenFactory.test.js.tap +74 -0
  94. package/.tap/test-results/test/internals/request-validate.test.js.tap +384 -0
  95. package/.tap/test-results/test/internals/request.test.js.tap +163 -0
  96. package/.tap/test-results/test/internals/server.test.js.tap +30 -0
  97. package/.tap/test-results/test/internals/validation.test.js.tap +121 -0
  98. package/.tap/test-results/test/keepAliveTimeout.test.js.tap +12 -0
  99. package/.tap/test-results/test/listen.1.test.js.tap +31 -0
  100. package/.tap/test-results/test/listen.2.test.js.tap +46 -0
  101. package/.tap/test-results/test/listen.3.test.js.tap +25 -0
  102. package/.tap/test-results/test/listen.4.test.js.tap +51 -0
  103. package/.tap/test-results/test/lock.test.js.tap +29 -0
  104. package/.tap/test-results/test/logger/instantiation.test.js.tap +92 -0
  105. package/.tap/test-results/test/logger/logging.test.js.tap +117 -0
  106. package/.tap/test-results/test/logger/options.test.js.tap +165 -0
  107. package/.tap/test-results/test/logger/request.test.js.tap +82 -0
  108. package/.tap/test-results/test/logger/response.test.js.tap +38 -0
  109. package/.tap/test-results/test/maxRequestsPerSocket.test.js.tap +44 -0
  110. package/.tap/test-results/test/method-missing.test.js.tap +8 -0
  111. package/.tap/test-results/test/middleware.test.js.tap +17 -0
  112. package/.tap/test-results/test/mkcalendar.test.js.tap +43 -0
  113. package/.tap/test-results/test/mkcol.test.js.tap +14 -0
  114. package/.tap/test-results/test/move.test.js.tap +15 -0
  115. package/.tap/test-results/test/noop-set.test.js.tap +8 -0
  116. package/.tap/test-results/test/nullable-validation.test.js.tap +36 -0
  117. package/.tap/test-results/test/options.error-handler.test.js.tap +186 -0
  118. package/.tap/test-results/test/options.test.js.tap +174 -0
  119. package/.tap/test-results/test/output-validation.test.js.tap +66 -0
  120. package/.tap/test-results/test/patch.error-handler.test.js.tap +206 -0
  121. package/.tap/test-results/test/patch.test.js.tap +182 -0
  122. package/.tap/test-results/test/plugin.1.test.js.tap +78 -0
  123. package/.tap/test-results/test/plugin.2.test.js.tap +102 -0
  124. package/.tap/test-results/test/plugin.3.test.js.tap +58 -0
  125. package/.tap/test-results/test/plugin.4.test.js.tap +164 -0
  126. package/.tap/test-results/test/post-empty-body.test.js.tap +8 -0
  127. package/.tap/test-results/test/pretty-print.test.js.tap +82 -0
  128. package/.tap/test-results/test/promises.test.js.tap +46 -0
  129. package/.tap/test-results/test/propfind.test.js.tap +43 -0
  130. package/.tap/test-results/test/proppatch.test.js.tap +29 -0
  131. package/.tap/test-results/test/proto-poisoning.test.js.tap +47 -0
  132. package/.tap/test-results/test/put.error-handler.test.js.tap +206 -0
  133. package/.tap/test-results/test/put.test.js.tap +182 -0
  134. package/.tap/test-results/test/register.test.js.tap +61 -0
  135. package/.tap/test-results/test/reply-code.test.js.tap +40 -0
  136. package/.tap/test-results/test/reply-earlyHints.test.js.tap +22 -0
  137. package/.tap/test-results/test/reply-error.test.js.tap +643 -0
  138. package/.tap/test-results/test/reply-trailers.test.js.tap +176 -0
  139. package/.tap/test-results/test/report.test.js.tap +43 -0
  140. package/.tap/test-results/test/request-error.test.js.tap +98 -0
  141. package/.tap/test-results/test/request-id.test.js.tap +38 -0
  142. package/.tap/test-results/test/request.deprecated.test.js.tap +13 -0
  143. package/.tap/test-results/test/requestTimeout.test.js.tap +21 -0
  144. package/.tap/test-results/test/route-hooks.test.js.tap +498 -0
  145. package/.tap/test-results/test/route-prefix.test.js.tap +195 -0
  146. package/.tap/test-results/test/route-shorthand.test.js.tap +190 -0
  147. package/.tap/test-results/test/route.1.test.js.tap +93 -0
  148. package/.tap/test-results/test/route.2.test.js.tap +28 -0
  149. package/.tap/test-results/test/route.3.test.js.tap +39 -0
  150. package/.tap/test-results/test/route.4.test.js.tap +32 -0
  151. package/.tap/test-results/test/route.5.test.js.tap +54 -0
  152. package/.tap/test-results/test/route.6.test.js.tap +81 -0
  153. package/.tap/test-results/test/route.7.test.js.tap +93 -0
  154. package/.tap/test-results/test/route.8.test.js.tap +38 -0
  155. package/.tap/test-results/test/router-options.test.js.tap +104 -0
  156. package/.tap/test-results/test/same-shape.test.js.tap +22 -0
  157. package/.tap/test-results/test/schema-examples.test.js.tap +85 -0
  158. package/.tap/test-results/test/schema-feature.test.js.tap +445 -0
  159. package/.tap/test-results/test/schema-serialization.test.js.tap +194 -0
  160. package/.tap/test-results/test/schema-special-usage.test.js.tap +186 -0
  161. package/.tap/test-results/test/schema-validation.test.js.tap +199 -0
  162. package/.tap/test-results/test/search.test.js.tap +77 -0
  163. package/.tap/test-results/test/serialize-response.test.js.tap +26 -0
  164. package/.tap/test-results/test/server.test.js.tap +65 -0
  165. package/.tap/test-results/test/set-error-handler.test.js.tap +7 -0
  166. package/.tap/test-results/test/skip-reply-send.test.js.tap +272 -0
  167. package/.tap/test-results/test/stream.1.test.js.tap +36 -0
  168. package/.tap/test-results/test/stream.2.test.js.tap +20 -0
  169. package/.tap/test-results/test/stream.3.test.js.tap +34 -0
  170. package/.tap/test-results/test/stream.4.test.js.tap +40 -0
  171. package/.tap/test-results/test/stream.5.test.js.tap +37 -0
  172. package/.tap/test-results/test/sync-routes.test.js.tap +19 -0
  173. package/.tap/test-results/test/throw.test.js.tap +116 -0
  174. package/.tap/test-results/test/trace.test.js.tap +7 -0
  175. package/.tap/test-results/test/trust-proxy.test.js.tap +109 -0
  176. package/.tap/test-results/test/type-provider.test.js.tap +12 -0
  177. package/.tap/test-results/test/unlock.test.js.tap +14 -0
  178. package/.tap/test-results/test/upgrade.test.js.tap +8 -0
  179. package/.tap/test-results/test/url-rewriting.test.js.tap +39 -0
  180. package/.tap/test-results/test/useSemicolonDelimiter.test.js.tap +33 -0
  181. package/.tap/test-results/test/validation-error-handling.test.js.tap +180 -0
  182. package/.tap/test-results/test/versioned-routes.test.js.tap +151 -0
  183. package/.tap/test-results/test/web-api.test.js.tap +51 -0
  184. package/.tap/test-results/test/wrapThenable.test.js.tap +11 -0
  185. package/.taprc +4 -8
  186. package/README.md +3 -6
  187. package/build/build-error-serializer.js +4 -1
  188. package/build/build-validation.js +5 -4
  189. package/docs/Guides/Database.md +1 -1
  190. package/docs/Guides/Delay-Accepting-Requests.md +3 -3
  191. package/docs/Guides/Ecosystem.md +2 -0
  192. package/docs/Guides/Migration-Guide-V5.md +20 -0
  193. package/docs/Guides/Write-Type-Provider.md +4 -2
  194. package/docs/Reference/ContentTypeParser.md +30 -1
  195. package/docs/Reference/Decorators.md +42 -16
  196. package/docs/Reference/Errors.md +10 -2
  197. package/docs/Reference/Hooks.md +48 -14
  198. package/docs/Reference/Logging.md +5 -5
  199. package/docs/Reference/Reply.md +29 -24
  200. package/docs/Reference/Request.md +5 -1
  201. package/docs/Reference/Routes.md +24 -28
  202. package/docs/Reference/Server.md +14 -53
  203. package/docs/Reference/Type-Providers.md +21 -26
  204. package/docs/Reference/TypeScript.md +46 -29
  205. package/docs/Reference/Warnings.md +2 -8
  206. package/eslint.config.js +27 -0
  207. package/examples/typescript-server.ts +14 -14
  208. package/fastify.d.ts +15 -14
  209. package/fastify.js +41 -15
  210. package/lib/configValidator.js +94 -76
  211. package/lib/contentTypeParser.js +54 -88
  212. package/lib/decorate.js +3 -7
  213. package/lib/error-serializer.js +77 -19
  214. package/lib/errors.js +31 -6
  215. package/lib/handleRequest.js +70 -39
  216. package/lib/httpMethods.js +34 -18
  217. package/lib/logger.js +24 -6
  218. package/lib/pluginUtils.js +5 -5
  219. package/lib/reply.js +16 -13
  220. package/lib/request.js +37 -19
  221. package/lib/route.js +7 -31
  222. package/lib/server.js +62 -123
  223. package/lib/warnings.js +28 -27
  224. package/lib/wrapThenable.js +46 -22
  225. package/package.json +38 -58
  226. package/test/404s.test.js +8 -12
  227. package/test/async-await.test.js +46 -2
  228. package/test/build/error-serializer.test.js +4 -2
  229. package/test/check.test.js +225 -0
  230. package/test/close-pipelining.test.js +2 -34
  231. package/test/close.test.js +1 -41
  232. package/test/content-parser.test.js +69 -117
  233. package/test/custom-parser.1.test.js +40 -1
  234. package/test/decorator-namespace.test._js_ +31 -0
  235. package/test/decorator.test.js +92 -43
  236. package/test/delete.test.js +21 -1
  237. package/test/diagnostics-channel/404.test.js +57 -0
  238. package/test/diagnostics-channel/async-delay-request.test.js +74 -0
  239. package/test/diagnostics-channel/async-request.test.js +72 -0
  240. package/test/diagnostics-channel/error-before-handler.test.js +36 -0
  241. package/test/diagnostics-channel/error-request.test.js +61 -0
  242. package/test/diagnostics-channel/error-status.test.js +39 -0
  243. package/test/{diagnostics-channel.test.js → diagnostics-channel/init.test.js} +6 -16
  244. package/test/diagnostics-channel/sync-delay-request.test.js +58 -0
  245. package/test/diagnostics-channel/sync-request-reply.test.js +58 -0
  246. package/test/diagnostics-channel/sync-request.test.js +61 -0
  247. package/test/encapsulated-error-handler.test.js +201 -14
  248. package/test/esm/index.test.js +2 -12
  249. package/test/findRoute.test.js +16 -0
  250. package/test/genReqId.test.js +9 -0
  251. package/test/get.test.js +28 -0
  252. package/test/has-route.test.js +18 -2
  253. package/test/helper.js +1 -5
  254. package/test/hooks.test.js +0 -4
  255. package/test/http2/constraint.test.js +22 -1
  256. package/test/http2/plain.test.js +21 -6
  257. package/test/http2/secure.test.js +12 -1
  258. package/test/https/https.test.js +57 -0
  259. package/test/inject.test.js +1 -2
  260. package/test/internals/decorator.test.js +0 -2
  261. package/test/internals/errors.test.js +57 -17
  262. package/test/internals/handleRequest.test.js +5 -1
  263. package/test/internals/initialConfig.test.js +5 -5
  264. package/test/internals/logger.test.js +31 -2
  265. package/test/internals/reply.test.js +38 -80
  266. package/test/internals/request.test.js +13 -11
  267. package/test/listen.1.test.js +5 -15
  268. package/test/listen.5.test.js +88 -0
  269. package/test/logger/instantiation.test.js +8 -8
  270. package/test/logger/logging.test.js +4 -4
  271. package/test/logger/options.test.js +102 -21
  272. package/test/logger/response.test.js +6 -6
  273. package/test/maxRequestsPerSocket.test.js +2 -5
  274. package/test/method-missing.test.js +24 -0
  275. package/test/plugin.1.test.js +2 -4
  276. package/test/plugin.2.test.js +0 -2
  277. package/test/plugin.3.test.js +0 -2
  278. package/test/plugin.4.test.js +92 -56
  279. package/test/register.test.js +2 -4
  280. package/test/reply-earlyHints.test.js +98 -0
  281. package/test/reply-error.test.js +0 -2
  282. package/test/route-hooks.test.js +0 -1
  283. package/test/route-shorthand.test.js +60 -0
  284. package/test/schema-special-usage.test.js +1 -1
  285. package/test/server.test.js +17 -2
  286. package/test/stream.2.test.js +1 -1
  287. package/test/stream.4.test.js +0 -42
  288. package/test/stream.5.test.js +2 -2
  289. package/test/trust-proxy.test.js +33 -27
  290. package/test/types/errors.test-d.ts +0 -2
  291. package/test/types/fastify.test-d.ts +14 -12
  292. package/test/types/hooks.test-d.ts +1 -0
  293. package/test/types/import.ts +1 -0
  294. package/test/types/instance.test-d.ts +10 -51
  295. package/test/types/logger.test-d.ts +43 -6
  296. package/test/types/plugin.test-d.ts +5 -2
  297. package/test/types/register.test-d.ts +2 -2
  298. package/test/types/reply.test-d.ts +13 -12
  299. package/test/types/request.test-d.ts +19 -8
  300. package/test/types/route.test-d.ts +30 -2
  301. package/test/types/schema.test-d.ts +2 -2
  302. package/test/types/serverFactory.test-d.ts +1 -1
  303. package/test/types/type-provider.test-d.ts +60 -13
  304. package/test/types/using.test-d.ts +4 -1
  305. package/test/url-rewriting.test.js +3 -2
  306. package/test/useSemicolonDelimiter.test.js +3 -6
  307. package/test/versioned-routes.test.js +1 -1
  308. package/test/web-api.test.js +0 -6
  309. package/types/content-type-parser.d.ts +3 -3
  310. package/types/context.d.ts +0 -1
  311. package/types/errors.d.ts +1 -0
  312. package/types/hooks.d.ts +6 -6
  313. package/types/instance.d.ts +28 -41
  314. package/types/logger.d.ts +3 -3
  315. package/types/plugin.d.ts +3 -3
  316. package/types/reply.d.ts +13 -14
  317. package/types/request.d.ts +5 -3
  318. package/types/route.d.ts +29 -29
  319. package/types/schema.d.ts +3 -3
  320. package/types/serverFactory.d.ts +2 -2
  321. package/types/type-provider.d.ts +22 -12
  322. package/types/utils.d.ts +18 -18
  323. package/.c8rc.json +0 -8
  324. package/.eslintrc +0 -4
  325. package/test/default-route.test.js +0 -88
  326. package/test/listen.deprecated.test.js +0 -229
  327. package/test/unsupported-httpversion.test.js +0 -31
  328. package/types/.eslintrc.json +0 -48
@@ -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
- 'DELETE',
6
- 'GET',
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
- hostname: req.hostname,
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 (!options.logger) {
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 (validateLogger(options.logger)) {
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.logger,
82
- serializers: Object.assign({}, serializers, options.logger.serializers)
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 => {
@@ -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 (!meta) return
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
- FSTWRN002(pluginName || 'anonymous')
141
+ throw new FST_ERR_PLUGIN_INVALID_ASYNC_HANDLER(pluginName)
142
142
  }
143
143
  }
144
144
 
package/lib/reply.js CHANGED
@@ -55,7 +55,7 @@ const {
55
55
  FST_ERR_MISSING_SERIALIZATION_FN,
56
56
  FST_ERR_MISSING_CONTENTTYPE_SERIALIZATION_FN
57
57
  } = require('./errors')
58
- const { FSTDEP010, FSTDEP013, FSTDEP019, FSTDEP020 } = require('./warnings')
58
+ const { FSTDEP010, FSTDEP013, FSTDEP019, FSTDEP021 } = require('./warnings')
59
59
 
60
60
  const toString = Object.prototype.toString
61
61
 
@@ -137,6 +137,11 @@ Object.defineProperties(Reply.prototype, {
137
137
  }
138
138
  })
139
139
 
140
+ Reply.prototype.writeEarlyHints = function (hints, callback) {
141
+ this.raw.writeEarlyHints(hints, callback)
142
+ return this
143
+ }
144
+
140
145
  Reply.prototype.hijack = function () {
141
146
  this[kReplyHijacked] = true
142
147
  return this
@@ -457,9 +462,15 @@ Reply.prototype.type = function (type) {
457
462
  return this
458
463
  }
459
464
 
460
- Reply.prototype.redirect = function (code, url) {
461
- if (typeof code === 'string') {
462
- url = code
465
+ Reply.prototype.redirect = function (url, code) {
466
+ if (typeof url === 'number') {
467
+ FSTDEP021()
468
+ const temp = code
469
+ code = url
470
+ url = temp
471
+ }
472
+
473
+ if (!code) {
463
474
  code = this[kReplyHasStatusCode] ? this.raw.statusCode : 302
464
475
  }
465
476
 
@@ -471,13 +482,6 @@ Reply.prototype.callNotFound = function () {
471
482
  return this
472
483
  }
473
484
 
474
- // TODO: should be removed in fastify@5
475
- Reply.prototype.getResponseTime = function () {
476
- FSTDEP020()
477
-
478
- return this.elapsedTime
479
- }
480
-
481
485
  // Make reply a thenable, so it could be used with async/await.
482
486
  // See
483
487
  // - https://github.com/fastify/fastify/issues/1864 for the discussions
@@ -904,9 +908,8 @@ function buildReply (R) {
904
908
  this[kReplyEndTime] = undefined
905
909
  this.log = log
906
910
 
907
- // eslint-disable-next-line no-var
908
911
  var prop
909
- // eslint-disable-next-line no-var
912
+
910
913
  for (var i = 0; i < props.length; i++) {
911
914
  prop = props[i]
912
915
  this[prop.key] = prop.value
package/lib/request.js CHANGED
@@ -1,7 +1,6 @@
1
1
  'use strict'
2
2
 
3
3
  const proxyAddr = require('proxy-addr')
4
- const semver = require('semver')
5
4
  const {
6
5
  FSTDEP005,
7
6
  FSTDEP012,
@@ -49,8 +48,8 @@ function getTrustProxyFn (tp) {
49
48
  return tp
50
49
  }
51
50
  if (tp === true) {
52
- // Support plain true/false
53
- return function () { return true }
51
+ // Support trusting everything
52
+ return null
54
53
  }
55
54
  if (typeof tp === 'number') {
56
55
  // Support trusting hop count
@@ -115,7 +114,8 @@ function buildRequestWithTrustProxy (R, trustProxy) {
115
114
  Object.defineProperties(_Request.prototype, {
116
115
  ip: {
117
116
  get () {
118
- return proxyAddr(this.raw, proxyFn)
117
+ const addrs = proxyAddr.all(this.raw, proxyFn)
118
+ return addrs[addrs.length - 1]
119
119
  }
120
120
  },
121
121
  ips: {
@@ -123,7 +123,7 @@ function buildRequestWithTrustProxy (R, trustProxy) {
123
123
  return proxyAddr.all(this.raw, proxyFn)
124
124
  }
125
125
  },
126
- hostname: {
126
+ host: {
127
127
  get () {
128
128
  if (this.ip !== undefined && this.headers['x-forwarded-host']) {
129
129
  return getLastEntryInMultiHeaderValue(this.headers['x-forwarded-host'])
@@ -238,10 +238,7 @@ Object.defineProperties(Request.prototype, {
238
238
  },
239
239
  connection: {
240
240
  get () {
241
- /* istanbul ignore next */
242
- if (semver.gte(process.versions.node, '13.0.0')) {
243
- FSTDEP005()
244
- }
241
+ FSTDEP005()
245
242
  return this.raw.connection
246
243
  }
247
244
  },
@@ -257,11 +254,32 @@ Object.defineProperties(Request.prototype, {
257
254
  }
258
255
  }
259
256
  },
260
- hostname: {
257
+ host: {
261
258
  get () {
262
259
  return this.raw.headers.host || this.raw.headers[':authority']
263
260
  }
264
261
  },
262
+ hostname: {
263
+ get () {
264
+ return (this.host).split(':')[0]
265
+ }
266
+ },
267
+ port: {
268
+ get () {
269
+ // first try taking port from host
270
+ const portFromHost = parseInt((this.host).split(':').slice(-1)[0])
271
+ if (!isNaN(portFromHost)) {
272
+ return portFromHost
273
+ }
274
+ // now fall back to port from host/:authority header
275
+ const portFromHeader = parseInt((this.headers.host || this.headers[':authority']).split(':').slice(-1)[0])
276
+ if (!isNaN(portFromHeader)) {
277
+ return portFromHeader
278
+ }
279
+ // fall back to null
280
+ return null
281
+ }
282
+ },
265
283
  protocol: {
266
284
  get () {
267
285
  if (this.socket) {
@@ -299,13 +317,13 @@ Object.defineProperties(Request.prototype, {
299
317
  }
300
318
 
301
319
  const validatorCompiler = this[kRouteContext].validatorCompiler ||
302
- this.server[kSchemaController].validatorCompiler ||
303
- (
304
- // We compile the schemas if no custom validatorCompiler is provided
305
- // nor set
306
- this.server[kSchemaController].setupValidator(this.server[kOptions]) ||
307
- this.server[kSchemaController].validatorCompiler
308
- )
320
+ this.server[kSchemaController].validatorCompiler ||
321
+ (
322
+ // We compile the schemas if no custom validatorCompiler is provided
323
+ // nor set
324
+ this.server[kSchemaController].setupValidator(this.server[kOptions]) ||
325
+ this.server[kSchemaController].validatorCompiler
326
+ )
309
327
 
310
328
  const validateFn = validatorCompiler({
311
329
  schema,
@@ -342,8 +360,8 @@ Object.defineProperties(Request.prototype, {
342
360
 
343
361
  // We cannot compile if the schema is missed
344
362
  if (validate == null && (schema == null ||
345
- typeof schema !== 'object' ||
346
- Array.isArray(schema))
363
+ typeof schema !== 'object' ||
364
+ Array.isArray(schema))
347
365
  ) {
348
366
  throw new FST_ERR_REQ_INVALID_VALIDATION_INVOCATION(httpPart)
349
367
  }
package/lib/route.js CHANGED
@@ -9,8 +9,7 @@ const { normalizeSchema } = require('./schemas')
9
9
  const { parseHeadOnSendHandlers } = require('./headRoute')
10
10
  const {
11
11
  FSTDEP007,
12
- FSTDEP008,
13
- FSTDEP014
12
+ FSTDEP008
14
13
  } = require('./warnings')
15
14
 
16
15
  const {
@@ -21,7 +20,6 @@ const {
21
20
  const {
22
21
  FST_ERR_SCH_VALIDATION_BUILD,
23
22
  FST_ERR_SCH_SERIALIZATION_BUILD,
24
- FST_ERR_DEFAULT_ROUTE_INVALID_TYPE,
25
23
  FST_ERR_DUPLICATED_ROUTE,
26
24
  FST_ERR_INVALID_URL,
27
25
  FST_ERR_HOOK_INVALID_HANDLER,
@@ -72,7 +70,6 @@ function buildRouting (options) {
72
70
  let ignoreDuplicateSlashes
73
71
  let return503OnClosing
74
72
  let globalExposeHeadRoutes
75
- let validateHTTPVersion
76
73
  let keepAliveConnections
77
74
 
78
75
  let closing = false
@@ -89,7 +86,6 @@ function buildRouting (options) {
89
86
  hasLogger = fastifyArgs.hasLogger
90
87
  setupResponseListeners = fastifyArgs.setupResponseListeners
91
88
  throwIfAlreadyStarted = fastifyArgs.throwIfAlreadyStarted
92
- validateHTTPVersion = fastifyArgs.validateHTTPVersion
93
89
 
94
90
  globalExposeHeadRoutes = options.exposeHeadRoutes
95
91
  disableRequestLogging = options.disableRequestLogging
@@ -102,18 +98,6 @@ function buildRouting (options) {
102
98
  route, // configure a route in the fastify instance
103
99
  hasRoute,
104
100
  prepareRoute,
105
- getDefaultRoute: function () {
106
- FSTDEP014()
107
- return router.defaultRoute
108
- },
109
- setDefaultRoute: function (defaultRoute) {
110
- FSTDEP014()
111
- if (typeof defaultRoute !== 'function') {
112
- throw new FST_ERR_DEFAULT_ROUTE_INVALID_TYPE()
113
- }
114
-
115
- router.defaultRoute = defaultRoute
116
- },
117
101
  routeHandler,
118
102
  closeRoutes: () => { closing = true },
119
103
  printRoutes: router.prettyPrint.bind(router),
@@ -168,7 +152,12 @@ function buildRouting (options) {
168
152
  }
169
153
 
170
154
  function hasRoute ({ options }) {
171
- return findRoute(options) !== null
155
+ const normalizedMethod = options.method?.toUpperCase() ?? ''
156
+ return router.hasRoute(
157
+ normalizedMethod,
158
+ options.url || '',
159
+ options.constraints
160
+ )
172
161
  }
173
162
 
174
163
  function findRoute (options) {
@@ -456,19 +445,6 @@ function buildRouting (options) {
456
445
  const childLogger = createChildLogger(context, logger, req, id, loggerOpts)
457
446
  childLogger[kDisableRequestLogging] = disableRequestLogging
458
447
 
459
- // TODO: The check here should be removed once https://github.com/nodejs/node/issues/43115 resolve in core.
460
- if (!validateHTTPVersion(req.httpVersion)) {
461
- childLogger.info({ res: { statusCode: 505 } }, 'request aborted - invalid HTTP version')
462
- const message = '{"error":"HTTP Version Not Supported","message":"HTTP Version Not Supported","statusCode":505}'
463
- const headers = {
464
- 'Content-Type': 'application/json',
465
- 'Content-Length': message.length
466
- }
467
- res.writeHead(505, headers)
468
- res.end(message)
469
- return
470
- }
471
-
472
448
  if (closing === true) {
473
449
  /* istanbul ignore next mac, windows */
474
450
  if (req.httpVersionMajor !== 2) {
package/lib/server.js CHANGED
@@ -3,8 +3,8 @@
3
3
  const http = require('node:http')
4
4
  const https = require('node:https')
5
5
  const dns = require('node:dns')
6
+ const os = require('node:os')
6
7
 
7
- const { FSTDEP011 } = require('./warnings')
8
8
  const { kState, kOptions, kServerBindings } = require('./symbols')
9
9
  const { onListenHookRunner } = require('./hooks')
10
10
  const {
@@ -15,7 +15,6 @@ const {
15
15
  } = require('./errors')
16
16
 
17
17
  module.exports.createServer = createServer
18
- module.exports.compileValidateHTTPVersion = compileValidateHTTPVersion
19
18
 
20
19
  function defaultResolveServerListeningText (address) {
21
20
  return `Server listening at ${address}`
@@ -25,27 +24,11 @@ function createServer (options, httpHandler) {
25
24
  const server = getServerInstance(options, httpHandler)
26
25
 
27
26
  // `this` is the Fastify object
28
- function listen (listenOptions, ...args) {
29
- let cb = args.slice(-1).pop()
30
- // When the variadic signature deprecation is complete, the function
31
- // declaration should become:
32
- // function listen (listenOptions = { port: 0, host: 'localhost' }, cb = undefined)
33
- // Upon doing so, the `normalizeListenArgs` function is no longer needed,
34
- // and all of this preamble to feed it correctly also no longer needed.
35
- const firstArgType = Object.prototype.toString.call(arguments[0])
36
- if (arguments.length === 0) {
37
- listenOptions = normalizeListenArgs([])
38
- } else if (arguments.length > 0 && (firstArgType !== '[object Object]' && firstArgType !== '[object Function]')) {
39
- FSTDEP011()
40
- listenOptions = normalizeListenArgs(Array.from(arguments))
41
- cb = listenOptions.cb
42
- } else if (args.length > 1) {
43
- // `.listen(obj, a, ..., n, callback )`
44
- FSTDEP011()
45
- // Deal with `.listen(port, host, backlog, [cb])`
46
- const hostPath = listenOptions.path ? [listenOptions.path] : [listenOptions.port ?? 0, listenOptions.host ?? 'localhost']
47
- Object.assign(listenOptions, normalizeListenArgs([...hostPath, ...args]))
48
- } else {
27
+ function listen (
28
+ listenOptions = { port: 0, host: 'localhost' },
29
+ cb = undefined
30
+ ) {
31
+ if (typeof cb === 'function') {
49
32
  listenOptions.cb = cb
50
33
  }
51
34
  if (listenOptions.signal) {
@@ -220,6 +203,7 @@ function multipleBindings (mainServer, httpHandler, serverOpts, listenOptions, o
220
203
  function listenCallback (server, listenOptions) {
221
204
  const wrap = (err) => {
222
205
  server.removeListener('error', wrap)
206
+ server.removeListener('listening', wrap)
223
207
  if (!err) {
224
208
  const address = logServerAddress.call(this, server, listenOptions.listenTextResolver || defaultResolveServerListeningText)
225
209
  listenOptions.cb(null, address)
@@ -240,7 +224,8 @@ function listenCallback (server, listenOptions) {
240
224
 
241
225
  server.once('error', wrap)
242
226
  if (!this[kState].closing) {
243
- server.listen(listenOptions, wrap)
227
+ server.once('listening', wrap)
228
+ server.listen(listenOptions)
244
229
  this[kState].listening = true
245
230
  }
246
231
  }
@@ -255,79 +240,37 @@ function listenPromise (server, listenOptions) {
255
240
 
256
241
  return this.ready().then(() => {
257
242
  let errEventHandler
243
+ let listeningEventHandler
244
+ function cleanup () {
245
+ server.removeListener('error', errEventHandler)
246
+ server.removeListener('listening', listeningEventHandler)
247
+ }
258
248
  const errEvent = new Promise((resolve, reject) => {
259
249
  errEventHandler = (err) => {
250
+ cleanup()
260
251
  this[kState].listening = false
261
252
  reject(err)
262
253
  }
263
254
  server.once('error', errEventHandler)
264
255
  })
265
- const listen = new Promise((resolve, reject) => {
266
- server.listen(listenOptions, () => {
267
- server.removeListener('error', errEventHandler)
256
+ const listeningEvent = new Promise((resolve, reject) => {
257
+ listeningEventHandler = () => {
258
+ cleanup()
259
+ this[kState].listening = true
268
260
  resolve(logServerAddress.call(this, server, listenOptions.listenTextResolver || defaultResolveServerListeningText))
269
- })
270
- // we set it afterwards because listen can throw
271
- this[kState].listening = true
261
+ }
262
+ server.once('listening', listeningEventHandler)
272
263
  })
273
264
 
265
+ server.listen(listenOptions)
266
+
274
267
  return Promise.race([
275
268
  errEvent, // e.g invalid port range error is always emitted before the server listening
276
- listen
269
+ listeningEvent
277
270
  ])
278
271
  })
279
272
  }
280
273
 
281
- /**
282
- * Creates a function that, based upon initial configuration, will
283
- * verify that every incoming request conforms to allowed
284
- * HTTP versions for the Fastify instance, e.g. a Fastify HTTP/1.1
285
- * server will not serve HTTP/2 requests upon the result of the
286
- * verification function.
287
- *
288
- * @param {object} options fastify option
289
- * @param {function} [options.serverFactory] If present, the
290
- * validator function will skip all checks.
291
- * @param {boolean} [options.http2 = false] If true, the validator
292
- * function will allow HTTP/2 requests.
293
- * @param {object} [options.https = null] https server options
294
- * @param {boolean} [options.https.allowHTTP1] If true and use
295
- * with options.http2 the validator function will allow HTTP/1
296
- * request to http2 server.
297
- *
298
- * @returns {function} HTTP version validator function.
299
- */
300
- function compileValidateHTTPVersion (options) {
301
- let bypass = false
302
- // key-value map to store valid http version
303
- const map = new Map()
304
- if (options.serverFactory) {
305
- // When serverFactory is passed, we cannot identify how to check http version reliably
306
- // So, we should skip the http version check
307
- bypass = true
308
- }
309
- if (options.http2) {
310
- // HTTP2 must serve HTTP/2.0
311
- map.set('2.0', true)
312
- if (options.https && options.https.allowHTTP1 === true) {
313
- // HTTP2 with HTTPS.allowHTTP1 allow fallback to HTTP/1.1 and HTTP/1.0
314
- map.set('1.1', true)
315
- map.set('1.0', true)
316
- }
317
- } else {
318
- // HTTP must server HTTP/1.1 and HTTP/1.0
319
- map.set('1.1', true)
320
- map.set('1.0', true)
321
- }
322
- // The compiled function here placed in one of the hottest path inside fastify
323
- // the implementation here must be as performant as possible
324
- return function validateHTTPVersion (httpVersion) {
325
- // `bypass` skip the check when custom server factory provided
326
- // `httpVersion in obj` check for the valid http version we should support
327
- return bypass || map.has(httpVersion)
328
- }
329
- }
330
-
331
274
  function getServerInstance (options, httpHandler) {
332
275
  let server = null
333
276
  // node@20 do not accepts options as boolean
@@ -364,57 +307,53 @@ function getServerInstance (options, httpHandler) {
364
307
  }
365
308
  return server
366
309
  }
367
-
368
- function normalizeListenArgs (args) {
369
- if (args.length === 0) {
370
- return { port: 0, host: 'localhost' }
371
- }
372
-
373
- const cb = typeof args[args.length - 1] === 'function' ? args.pop() : undefined
374
- const options = { cb }
375
-
376
- const firstArg = args[0]
377
- const argsLength = args.length
378
- const lastArg = args[argsLength - 1]
379
- if (typeof firstArg === 'string' && isNaN(firstArg)) {
380
- /* Deal with listen (pipe[, backlog]) */
381
- options.path = firstArg
382
- options.backlog = argsLength > 1 ? lastArg : undefined
383
- } else {
384
- /* Deal with listen ([port[, host[, backlog]]]) */
385
- options.port = argsLength >= 1 && Number.isInteger(firstArg) ? firstArg : normalizePort(firstArg)
386
- // This will listen to what localhost is.
387
- // It can be 127.0.0.1 or ::1, depending on the operating system.
388
- // Fixes https://github.com/fastify/fastify/issues/1022.
389
- options.host = argsLength >= 2 && args[1] ? args[1] : 'localhost'
390
- options.backlog = argsLength >= 3 ? args[2] : undefined
310
+ /**
311
+ * Inspects the provided `server.address` object and returns a
312
+ * normalized list of IP address strings. Normalization in this
313
+ * case refers to mapping wildcard `0.0.0.0` to the list of IP
314
+ * addresses the wildcard refers to.
315
+ *
316
+ * @see https://nodejs.org/docs/latest/api/net.html#serveraddress
317
+ *
318
+ * @param {object} A server address object as described in the
319
+ * linked docs.
320
+ *
321
+ * @returns {string[]}
322
+ */
323
+ function getAddresses (address) {
324
+ if (address.address === '0.0.0.0') {
325
+ return Object.values(os.networkInterfaces()).flatMap((iface) => {
326
+ return iface.filter((iface) => iface.family === 'IPv4')
327
+ }).sort((iface) => {
328
+ /* c8 ignore next 2 */
329
+ // Order the interfaces so that internal ones come first
330
+ return iface.internal ? -1 : 1
331
+ }).map((iface) => { return iface.address })
391
332
  }
392
-
393
- return options
394
- }
395
-
396
- function normalizePort (firstArg) {
397
- const port = Number(firstArg)
398
- return port >= 0 && !Number.isNaN(port) && Number.isInteger(port) ? port : 0
333
+ return [address.address]
399
334
  }
400
335
 
401
336
  function logServerAddress (server, listenTextResolver) {
402
- let address = server.address()
403
- const isUnixSocket = typeof address === 'string'
404
- /* istanbul ignore next */
337
+ let addresses
338
+ const isUnixSocket = typeof server.address() === 'string'
405
339
  if (!isUnixSocket) {
406
- if (address.address.indexOf(':') === -1) {
407
- address = address.address + ':' + address.port
340
+ if (server.address().address.indexOf(':') === -1) {
341
+ // IPv4
342
+ addresses = getAddresses(server.address()).map((address) => address + ':' + server.address().port)
408
343
  } else {
409
- address = '[' + address.address + ']:' + address.port
344
+ // IPv6
345
+ addresses = ['[' + server.address().address + ']:' + server.address().port]
410
346
  }
347
+
348
+ addresses = addresses.map((address) => ('http' + (this[kOptions].https ? 's' : '') + '://') + address)
349
+ } else {
350
+ addresses = [server.address()]
411
351
  }
412
- /* istanbul ignore next */
413
- address = (isUnixSocket ? '' : ('http' + (this[kOptions].https ? 's' : '') + '://')) + address
414
352
 
415
- const serverListeningText = listenTextResolver(address)
416
- this.log.info(serverListeningText)
417
- return address
353
+ for (const address of addresses) {
354
+ this.log.info(listenTextResolver(address))
355
+ }
356
+ return addresses[0]
418
357
  }
419
358
 
420
359
  function http2 () {