fastify 3.27.4 → 4.0.0-alpha.3

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 (168) hide show
  1. package/.taprc +3 -0
  2. package/README.md +7 -7
  3. package/build/build-error-serializer.js +27 -0
  4. package/build/build-validation.js +47 -35
  5. package/docs/Guides/Database.md +320 -0
  6. package/docs/Guides/Ecosystem.md +9 -0
  7. package/docs/Guides/Getting-Started.md +7 -7
  8. package/docs/Guides/Plugins-Guide.md +1 -1
  9. package/docs/Guides/Serverless.md +3 -3
  10. package/docs/Guides/Testing.md +2 -2
  11. package/docs/Migration-Guide-V4.md +12 -0
  12. package/docs/Reference/ContentTypeParser.md +4 -0
  13. package/docs/Reference/Decorators.md +2 -2
  14. package/docs/Reference/Encapsulation.md +2 -2
  15. package/docs/Reference/Errors.md +51 -6
  16. package/docs/Reference/HTTP2.md +3 -3
  17. package/docs/Reference/Hooks.md +4 -7
  18. package/docs/Reference/LTS.md +5 -4
  19. package/docs/Reference/Plugins.md +3 -3
  20. package/docs/Reference/Reply.md +73 -22
  21. package/docs/Reference/Request.md +1 -3
  22. package/docs/Reference/Routes.md +22 -15
  23. package/docs/Reference/Server.md +69 -119
  24. package/docs/Reference/TypeScript.md +20 -22
  25. package/docs/Reference/Validation-and-Serialization.md +30 -55
  26. package/docs/Type-Providers.md +257 -0
  27. package/examples/asyncawait.js +1 -1
  28. package/examples/benchmark/hooks-benchmark-async-await.js +1 -1
  29. package/examples/benchmark/hooks-benchmark.js +1 -1
  30. package/examples/benchmark/simple.js +1 -1
  31. package/examples/hooks.js +2 -2
  32. package/examples/http2.js +1 -1
  33. package/examples/https.js +1 -1
  34. package/examples/parser.js +13 -3
  35. package/examples/route-prefix.js +1 -1
  36. package/examples/shared-schema.js +1 -1
  37. package/examples/simple-stream.js +18 -0
  38. package/examples/simple.js +1 -1
  39. package/examples/simple.mjs +1 -1
  40. package/examples/typescript-server.ts +1 -1
  41. package/examples/use-plugin.js +1 -1
  42. package/fastify.d.ts +34 -22
  43. package/fastify.js +40 -36
  44. package/lib/configValidator.js +902 -1023
  45. package/lib/contentTypeParser.js +6 -16
  46. package/lib/context.js +36 -10
  47. package/lib/decorate.js +3 -1
  48. package/lib/error-handler.js +158 -0
  49. package/lib/error-serializer.js +257 -0
  50. package/lib/errors.js +51 -9
  51. package/lib/fourOhFour.js +31 -20
  52. package/lib/handleRequest.js +10 -13
  53. package/lib/hooks.js +14 -9
  54. package/lib/pluginOverride.js +0 -3
  55. package/lib/pluginUtils.js +3 -2
  56. package/lib/reply.js +121 -175
  57. package/lib/request.js +13 -10
  58. package/lib/route.js +131 -138
  59. package/lib/schema-controller.js +2 -2
  60. package/lib/schemas.js +27 -1
  61. package/lib/server.js +242 -116
  62. package/lib/symbols.js +5 -3
  63. package/lib/validation.js +11 -9
  64. package/lib/warnings.js +4 -12
  65. package/lib/wrapThenable.js +4 -11
  66. package/package.json +37 -39
  67. package/test/404s.test.js +258 -125
  68. package/test/500s.test.js +3 -3
  69. package/test/als.test.js +1 -1
  70. package/test/async-await.test.js +20 -76
  71. package/test/bodyLimit.test.js +1 -1
  72. package/test/build-certificate.js +6 -7
  73. package/test/case-insensitive.test.js +4 -4
  74. package/test/close-pipelining.test.js +2 -2
  75. package/test/close.test.js +11 -11
  76. package/test/content-parser.test.js +32 -0
  77. package/test/context-config.test.js +52 -0
  78. package/test/custom-http-server.test.js +14 -7
  79. package/test/custom-parser-async.test.js +1 -66
  80. package/test/custom-parser.test.js +92 -159
  81. package/test/custom-querystring-parser.test.js +3 -3
  82. package/test/decorator.test.js +11 -13
  83. package/test/delete.test.js +6 -6
  84. package/test/encapsulated-error-handler.test.js +50 -0
  85. package/test/esm/index.test.js +0 -14
  86. package/test/fastify-instance.test.js +4 -4
  87. package/test/fluent-schema.test.js +4 -4
  88. package/test/genReqId.test.js +1 -1
  89. package/test/get.test.js +4 -4
  90. package/test/handler-context.test.js +2 -2
  91. package/test/head.test.js +1 -1
  92. package/test/helper.js +19 -4
  93. package/test/hooks-async.test.js +15 -48
  94. package/test/hooks.on-ready.test.js +10 -5
  95. package/test/hooks.test.js +78 -119
  96. package/test/http2/closing.test.js +10 -16
  97. package/test/http2/constraint.test.js +1 -1
  98. package/test/http2/head.test.js +1 -1
  99. package/test/http2/plain.test.js +1 -1
  100. package/test/http2/secure-with-fallback.test.js +1 -1
  101. package/test/http2/secure.test.js +1 -1
  102. package/test/http2/unknown-http-method.test.js +4 -10
  103. package/test/https/custom-https-server.test.js +12 -6
  104. package/test/https/https.test.js +1 -1
  105. package/test/input-validation.js +3 -3
  106. package/test/internals/handleRequest.test.js +6 -43
  107. package/test/internals/initialConfig.test.js +41 -12
  108. package/test/internals/logger.test.js +2 -2
  109. package/test/internals/reply.test.js +317 -48
  110. package/test/internals/request.test.js +13 -7
  111. package/test/internals/server.test.js +88 -0
  112. package/test/listen.deprecated.test.js +202 -0
  113. package/test/listen.test.js +140 -145
  114. package/test/logger.test.js +82 -42
  115. package/test/maxRequestsPerSocket.test.js +8 -6
  116. package/test/middleware.test.js +2 -25
  117. package/test/nullable-validation.test.js +53 -16
  118. package/test/output-validation.test.js +1 -1
  119. package/test/plugin.test.js +47 -21
  120. package/test/pretty-print.test.js +22 -10
  121. package/test/promises.test.js +1 -1
  122. package/test/proto-poisoning.test.js +6 -6
  123. package/test/register.test.js +3 -3
  124. package/test/reply-error.test.js +126 -15
  125. package/test/reply-trailers.test.js +270 -0
  126. package/test/request-error.test.js +3 -6
  127. package/test/route-hooks.test.js +18 -18
  128. package/test/route-prefix.test.js +2 -1
  129. package/test/route.test.js +206 -22
  130. package/test/router-options.test.js +2 -2
  131. package/test/schema-examples.test.js +11 -5
  132. package/test/schema-feature.test.js +25 -20
  133. package/test/schema-serialization.test.js +9 -9
  134. package/test/schema-special-usage.test.js +5 -153
  135. package/test/schema-validation.test.js +9 -9
  136. package/test/skip-reply-send.test.js +2 -2
  137. package/test/stream.test.js +82 -23
  138. package/test/throw.test.js +8 -5
  139. package/test/trust-proxy.test.js +6 -6
  140. package/test/type-provider.test.js +20 -0
  141. package/test/types/fastify.test-d.ts +10 -18
  142. package/test/types/hooks.test-d.ts +61 -5
  143. package/test/types/import.js +2 -0
  144. package/test/types/import.ts +1 -0
  145. package/test/types/instance.test-d.ts +68 -17
  146. package/test/types/logger.test-d.ts +44 -15
  147. package/test/types/reply.test-d.ts +2 -1
  148. package/test/types/request.test-d.ts +71 -1
  149. package/test/types/route.test-d.ts +8 -2
  150. package/test/types/schema.test-d.ts +2 -39
  151. package/test/types/type-provider.test-d.ts +424 -0
  152. package/test/url-rewriting.test.js +3 -3
  153. package/test/validation-error-handling.test.js +8 -8
  154. package/test/versioned-routes.test.js +30 -18
  155. package/test/wrapThenable.test.js +7 -6
  156. package/types/content-type-parser.d.ts +17 -8
  157. package/types/hooks.d.ts +182 -85
  158. package/types/instance.d.ts +286 -118
  159. package/types/logger.d.ts +18 -104
  160. package/types/plugin.d.ts +10 -4
  161. package/types/reply.d.ts +18 -12
  162. package/types/request.d.ts +13 -8
  163. package/types/route.d.ts +62 -34
  164. package/types/schema.d.ts +1 -1
  165. package/types/type-provider.d.ts +99 -0
  166. package/types/utils.d.ts +1 -1
  167. package/lib/schema-compilers.js +0 -12
  168. package/test/emit-warning.test.js +0 -166
@@ -4,8 +4,10 @@ const os = require('os')
4
4
  const path = require('path')
5
5
  const fs = require('fs')
6
6
  const { test, before } = require('tap')
7
- const Fastify = require('..')
8
7
  const dns = require('dns').promises
8
+ const dnsCb = require('dns')
9
+ const sget = require('simple-get').concat
10
+ const Fastify = require('..')
9
11
 
10
12
  let localhost
11
13
  let localhostForURL
@@ -20,99 +22,77 @@ before(async function () {
20
22
  }
21
23
  })
22
24
 
23
- test('listen accepts a callback', t => {
24
- t.plan(2)
25
- const fastify = Fastify()
26
- t.teardown(fastify.close.bind(fastify))
27
- fastify.listen((err) => {
28
- t.equal(fastify.server.address().address, localhost)
29
- t.error(err)
25
+ test('listen works without arguments', async t => {
26
+ process.on('warning', () => {
27
+ t.fail('should not be deprecated')
30
28
  })
31
- })
32
29
 
33
- test('listen accepts a port and a callback', t => {
34
- t.plan(2)
35
30
  const fastify = Fastify()
36
31
  t.teardown(fastify.close.bind(fastify))
37
- fastify.listen(0, (err) => {
38
- t.equal(fastify.server.address().address, localhost)
39
- t.error(err)
40
- })
32
+ await fastify.listen()
33
+ const address = fastify.server.address()
34
+ t.equal(address.address, localhost)
35
+ t.ok(address.port > 0)
41
36
  })
42
37
 
43
- test('listen accepts a port and a callback with (err, address)', t => {
44
- t.plan(2)
45
- const fastify = Fastify()
46
- t.teardown(fastify.close.bind(fastify))
47
- fastify.listen(0, (err, address) => {
48
- t.equal(address, `http://${localhostForURL}:${fastify.server.address().port}`)
49
- t.error(err)
38
+ test('Async/await listen with arguments', async t => {
39
+ process.on('warning', () => {
40
+ t.fail('should not be deprecated')
50
41
  })
51
- })
52
42
 
53
- test('listen accepts a port, address, and callback', t => {
54
43
  t.plan(1)
55
44
  const fastify = Fastify()
56
45
  t.teardown(fastify.close.bind(fastify))
57
- fastify.listen(0, localhost, (err) => {
58
- t.error(err)
59
- })
46
+ const addr = await fastify.listen({ port: 0, host: '0.0.0.0' })
47
+ const address = fastify.server.address()
48
+ t.equal(addr, `http://${address.address}:${address.port}`)
60
49
  })
61
50
 
62
- test('listen accepts options and a callback', t => {
63
- t.plan(1)
64
- const fastify = Fastify()
65
- t.teardown(fastify.close.bind(fastify))
66
- fastify.listen({
67
- port: 0,
68
- host: 'localhost',
69
- backlog: 511,
70
- exclusive: false,
71
- readableAll: false,
72
- writableAll: false,
73
- ipv6Only: false
74
- }, (err) => {
75
- t.error(err)
51
+ test('Promise listen with arguments', t => {
52
+ process.on('warning', () => {
53
+ t.fail('should not be deprecated')
76
54
  })
77
- })
78
55
 
79
- test('listen accepts options, backlog and a callback', t => {
80
56
  t.plan(1)
81
57
  const fastify = Fastify()
82
58
  t.teardown(fastify.close.bind(fastify))
83
- fastify.listen({
84
- port: 0,
85
- host: 'localhost'
86
- }, 511, (err) => {
87
- t.error(err)
59
+ fastify.listen({ port: 0, host: '0.0.0.0' }).then(addr => {
60
+ const address = fastify.server.address()
61
+ t.equal(addr, `http://${address.address}:${address.port}`)
88
62
  })
89
63
  })
90
64
 
91
- test('listen accepts a port, address and a callback with (err, address)', t => {
65
+ test('listen accepts a callback', t => {
66
+ process.on('warning', () => {
67
+ t.fail('should not be deprecated')
68
+ })
69
+
92
70
  t.plan(2)
93
71
  const fastify = Fastify()
94
72
  t.teardown(fastify.close.bind(fastify))
95
- fastify.listen(0, localhost, (err, address) => {
96
- t.equal(address, `http://${localhostForURL}:${fastify.server.address().port}`)
73
+ fastify.listen({ port: 0 }, (err) => {
74
+ t.equal(fastify.server.address().address, localhost)
97
75
  t.error(err)
98
76
  })
99
77
  })
100
78
 
101
- test('listen accepts a port, address, backlog and callback', t => {
102
- t.plan(1)
103
- const fastify = Fastify()
104
- t.teardown(fastify.close.bind(fastify))
105
- fastify.listen(0, localhost, 511, (err) => {
106
- t.error(err)
79
+ test('listen accepts options and a callback', t => {
80
+ process.on('warning', () => {
81
+ t.fail('should not be deprecated')
107
82
  })
108
- })
109
83
 
110
- test('listen accepts a port, address, backlog and callback with (err, address)', t => {
111
- t.plan(2)
84
+ t.plan(1)
112
85
  const fastify = Fastify()
113
86
  t.teardown(fastify.close.bind(fastify))
114
- fastify.listen(0, localhost, 511, (err, address) => {
115
- t.equal(address, `http://${localhostForURL}:${fastify.server.address().port}`)
87
+ fastify.listen({
88
+ port: 0,
89
+ host: 'localhost',
90
+ backlog: 511,
91
+ exclusive: false,
92
+ readableAll: false,
93
+ writableAll: false,
94
+ ipv6Only: false
95
+ }, (err) => {
116
96
  t.error(err)
117
97
  })
118
98
  })
@@ -123,7 +103,7 @@ test('listen after Promise.resolve()', t => {
123
103
  t.teardown(f.close.bind(f))
124
104
  Promise.resolve()
125
105
  .then(() => {
126
- f.listen(0, (err, address) => {
106
+ f.listen({ port: 0 }, (err, address) => {
127
107
  f.server.unref()
128
108
  t.equal(address, `http://${localhostForURL}:${f.server.address().port}`)
129
109
  t.error(err)
@@ -153,9 +133,9 @@ test('double listen errors', t => {
153
133
  t.plan(3)
154
134
  const fastify = Fastify()
155
135
  t.teardown(fastify.close.bind(fastify))
156
- fastify.listen(0, (err) => {
136
+ fastify.listen({ port: 0 }, (err) => {
157
137
  t.error(err)
158
- fastify.listen(fastify.server.address().port, (err, address) => {
138
+ fastify.listen({ port: fastify.server.address().port }, (err, address) => {
159
139
  t.equal(address, null)
160
140
  t.ok(err)
161
141
  })
@@ -166,10 +146,10 @@ test('double listen errors callback with (err, address)', t => {
166
146
  t.plan(4)
167
147
  const fastify = Fastify()
168
148
  t.teardown(fastify.close.bind(fastify))
169
- fastify.listen(0, (err1, address1) => {
149
+ fastify.listen({ port: 0 }, (err1, address1) => {
170
150
  t.equal(address1, `http://${localhostForURL}:${fastify.server.address().port}`)
171
151
  t.error(err1)
172
- fastify.listen(fastify.server.address().port, (err2, address2) => {
152
+ fastify.listen({ port: fastify.server.address().port }, (err2, address2) => {
173
153
  t.equal(address2, null)
174
154
  t.ok(err2)
175
155
  })
@@ -180,12 +160,12 @@ test('listen twice on the same port', t => {
180
160
  t.plan(4)
181
161
  const fastify = Fastify()
182
162
  t.teardown(fastify.close.bind(fastify))
183
- fastify.listen(0, (err1, address1) => {
163
+ fastify.listen({ port: 0 }, (err1, address1) => {
184
164
  t.equal(address1, `http://${localhostForURL}:${fastify.server.address().port}`)
185
165
  t.error(err1)
186
166
  const s2 = Fastify()
187
167
  t.teardown(s2.close.bind(s2))
188
- s2.listen(fastify.server.address().port, (err2, address2) => {
168
+ s2.listen({ port: fastify.server.address().port }, (err2, address2) => {
189
169
  t.equal(address2, null)
190
170
  t.ok(err2)
191
171
  })
@@ -196,13 +176,13 @@ test('listen twice on the same port callback with (err, address)', t => {
196
176
  t.plan(4)
197
177
  const fastify = Fastify()
198
178
  t.teardown(fastify.close.bind(fastify))
199
- fastify.listen(0, (err1, address1) => {
179
+ fastify.listen({ port: 0 }, (err1, address1) => {
200
180
  const _port = fastify.server.address().port
201
181
  t.equal(address1, `http://${localhostForURL}:${_port}`)
202
182
  t.error(err1)
203
183
  const s2 = Fastify()
204
184
  t.teardown(s2.close.bind(s2))
205
- s2.listen(_port, (err2, address2) => {
185
+ s2.listen({ port: _port }, (err2, address2) => {
206
186
  t.equal(address2, null)
207
187
  t.ok(err2)
208
188
  })
@@ -221,7 +201,7 @@ if (os.platform() !== 'win32') {
221
201
  fs.unlinkSync(sockFile)
222
202
  } catch (e) { }
223
203
 
224
- fastify.listen(sockFile, (err, address) => {
204
+ fastify.listen({ path: sockFile }, (err, address) => {
225
205
  t.error(err)
226
206
  t.equal(sockFile, fastify.server.address())
227
207
  t.equal(address, sockFile)
@@ -229,61 +209,11 @@ if (os.platform() !== 'win32') {
229
209
  })
230
210
  }
231
211
 
232
- test('listen without callback (port zero)', t => {
233
- t.plan(1)
234
- const fastify = Fastify()
235
- t.teardown(fastify.close.bind(fastify))
236
- fastify.listen(0)
237
- .then(() => {
238
- t.equal(fastify.server.address().address, localhost)
239
- })
240
- })
241
-
242
- test('listen without callback (port not given)', t => {
243
- t.plan(1)
244
- const fastify = Fastify()
245
- t.teardown(fastify.close.bind(fastify))
246
- fastify.listen()
247
- .then(() => {
248
- t.equal(fastify.server.address().address, localhost)
249
- })
250
- })
251
-
252
- test('listen null without callback with (address)', t => {
253
- t.plan(1)
254
- const fastify = Fastify()
255
- t.teardown(fastify.close.bind(fastify))
256
- fastify.listen(null)
257
- .then(address => {
258
- t.equal(address, `http://${localhostForURL}:${fastify.server.address().port}`)
259
- })
260
- })
261
-
262
- test('listen without port without callback with (address)', t => {
263
- t.plan(1)
264
- const fastify = Fastify()
265
- t.teardown(fastify.close.bind(fastify))
266
- fastify.listen()
267
- .then(address => {
268
- t.equal(address, `http://${localhostForURL}:${fastify.server.address().port}`)
269
- })
270
- })
271
-
272
- test('listen with undefined without callback with (address)', t => {
273
- t.plan(1)
274
- const fastify = Fastify()
275
- t.teardown(fastify.close.bind(fastify))
276
- fastify.listen(undefined)
277
- .then(address => {
278
- t.equal(address, `http://${localhostForURL}:${fastify.server.address().port}`)
279
- })
280
- })
281
-
282
212
  test('listen without callback with (address)', t => {
283
213
  t.plan(1)
284
214
  const fastify = Fastify()
285
215
  t.teardown(fastify.close.bind(fastify))
286
- fastify.listen(0)
216
+ fastify.listen({ port: 0 })
287
217
  .then(address => {
288
218
  t.equal(address, `http://${localhostForURL}:${fastify.server.address().port}`)
289
219
  })
@@ -293,9 +223,9 @@ test('double listen without callback rejects', t => {
293
223
  t.plan(1)
294
224
  const fastify = Fastify()
295
225
  t.teardown(fastify.close.bind(fastify))
296
- fastify.listen(0)
226
+ fastify.listen({ port: 0 })
297
227
  .then(() => {
298
- fastify.listen(0)
228
+ fastify.listen({ port: 0 })
299
229
  .catch(err => {
300
230
  t.ok(err)
301
231
  })
@@ -307,10 +237,10 @@ test('double listen without callback with (address)', t => {
307
237
  t.plan(2)
308
238
  const fastify = Fastify()
309
239
  t.teardown(fastify.close.bind(fastify))
310
- fastify.listen(0)
240
+ fastify.listen({ port: 0 })
311
241
  .then(address => {
312
242
  t.equal(address, `http://${localhostForURL}:${fastify.server.address().port}`)
313
- fastify.listen(0)
243
+ fastify.listen({ port: 0 })
314
244
  .catch(err => {
315
245
  t.ok(err)
316
246
  })
@@ -323,11 +253,11 @@ test('listen twice on the same port without callback rejects', t => {
323
253
  const fastify = Fastify()
324
254
  t.teardown(fastify.close.bind(fastify))
325
255
 
326
- fastify.listen(0)
256
+ fastify.listen({ port: 0 })
327
257
  .then(() => {
328
258
  const s2 = Fastify()
329
259
  t.teardown(s2.close.bind(s2))
330
- s2.listen(fastify.server.address().port)
260
+ s2.listen({ port: fastify.server.address().port })
331
261
  .catch(err => {
332
262
  t.ok(err)
333
263
  })
@@ -339,12 +269,12 @@ test('listen twice on the same port without callback rejects with (address)', t
339
269
  t.plan(2)
340
270
  const fastify = Fastify()
341
271
  t.teardown(fastify.close.bind(fastify))
342
- fastify.listen(0)
272
+ fastify.listen({ port: 0 })
343
273
  .then(address => {
344
274
  const s2 = Fastify()
345
275
  t.teardown(s2.close.bind(s2))
346
276
  t.equal(address, `http://${localhostForURL}:${fastify.server.address().port}`)
347
- s2.listen(fastify.server.address().port)
277
+ s2.listen({ port: fastify.server.address().port })
348
278
  .catch(err => {
349
279
  t.ok(err)
350
280
  })
@@ -355,7 +285,7 @@ test('listen twice on the same port without callback rejects with (address)', t
355
285
  test('listen on invalid port without callback rejects', t => {
356
286
  const fastify = Fastify()
357
287
  t.teardown(fastify.close.bind(fastify))
358
- return fastify.listen(-1)
288
+ return fastify.listen({ port: -1 })
359
289
  .catch(err => {
360
290
  t.ok(err)
361
291
  return true
@@ -372,24 +302,89 @@ test('listen logs the port as info', t => {
372
302
  msgs.push(msg)
373
303
  }
374
304
 
375
- fastify.listen(0)
305
+ fastify.listen({ port: 0 })
376
306
  .then(() => {
377
307
  t.ok(/http:\/\//.test(msgs[0]))
378
308
  })
379
309
  })
380
310
 
381
- test('listen when firstArg is string(pipe) and without backlog', async t => {
382
- t.plan(1)
383
- const fastify = Fastify()
384
- t.teardown(fastify.close.bind(fastify))
385
- const address = await fastify.listen('\\\\.\\pipe\\testPipe')
386
- t.equal(address, '\\\\.\\pipe\\testPipe')
311
+ test('listen on localhost binds IPv4 and IPv6 - promise interface', async t => {
312
+ const lookups = await dns.lookup('localhost', { all: true })
313
+ t.plan(2 * lookups.length)
314
+
315
+ const app = Fastify()
316
+ app.get('/', async () => 'hello localhost')
317
+ t.teardown(app.close.bind(app))
318
+ await app.listen({ port: 0, host: 'localhost' })
319
+
320
+ for (const lookup of lookups) {
321
+ await new Promise((resolve, reject) => {
322
+ sget({
323
+ method: 'GET',
324
+ url: getUrl(app, lookup)
325
+ }, (err, response, body) => {
326
+ if (err) { return reject(err) }
327
+ t.equal(response.statusCode, 200)
328
+ t.same(body.toString(), 'hello localhost')
329
+ resolve()
330
+ })
331
+ })
332
+ }
387
333
  })
388
334
 
389
- test('listen when firstArg is string(pipe) and with backlog', async t => {
390
- t.plan(1)
391
- const fastify = Fastify()
392
- t.teardown(fastify.close.bind(fastify))
393
- const address = await fastify.listen('\\\\.\\pipe\\testPipe', 511)
394
- t.equal(address, '\\\\.\\pipe\\testPipe')
335
+ test('listen on localhost binds to all interfaces (both IPv4 and IPv6 if present) - callback interface', t => {
336
+ dnsCb.lookup('localhost', { all: true }, (err, lookups) => {
337
+ t.plan(2 + (3 * lookups.length))
338
+ t.error(err)
339
+
340
+ const app = Fastify()
341
+ app.get('/', async () => 'hello localhost')
342
+ app.listen({ port: 0, host: 'localhost' }, (err) => {
343
+ t.error(err)
344
+ t.teardown(app.close.bind(app))
345
+
346
+ for (const lookup of lookups) {
347
+ sget({
348
+ method: 'GET',
349
+ url: getUrl(app, lookup)
350
+ }, (err, response, body) => {
351
+ t.error(err)
352
+ t.equal(response.statusCode, 200)
353
+ t.same(body.toString(), 'hello localhost')
354
+ })
355
+ }
356
+ })
357
+ })
395
358
  })
359
+
360
+ test('addresses getter', async t => {
361
+ t.plan(4)
362
+ const app = Fastify()
363
+ app.get('/', async () => 'hello localhost')
364
+
365
+ t.same(app.addresses(), [], 'before ready')
366
+ await app.ready()
367
+
368
+ t.same(app.addresses(), [], 'after ready')
369
+ await app.listen({ port: 0, host: 'localhost' })
370
+ const { port } = app.server.address()
371
+ const localAddresses = await dns.lookup('localhost', { all: true })
372
+ for (const address of localAddresses) {
373
+ address.port = port
374
+ address.family = 'IPv' + address.family
375
+ }
376
+ localAddresses.sort((a, b) => a.address.localeCompare(b.address))
377
+ t.same(app.addresses().sort((a, b) => a.address.localeCompare(b.address)), localAddresses, 'after listen')
378
+
379
+ await app.close()
380
+ t.same(app.addresses(), [], 'after close')
381
+ })
382
+
383
+ function getUrl (fastify, lookup) {
384
+ const { port } = fastify.server.address()
385
+ if (lookup.family === 6) {
386
+ return `http://[${lookup.address}]:${port}/`
387
+ } else {
388
+ return `http://${lookup.address}:${port}/`
389
+ }
390
+ }