fastify 5.3.3 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/build/build-validation.js +2 -1
- package/docs/Guides/Delay-Accepting-Requests.md +3 -3
- package/docs/Guides/Ecosystem.md +9 -5
- package/docs/Reference/ContentTypeParser.md +1 -1
- package/docs/Reference/Errors.md +2 -2
- package/docs/Reference/Hooks.md +14 -14
- package/docs/Reference/Logging.md +3 -3
- package/docs/Reference/Middleware.md +1 -1
- package/docs/Reference/Reply.md +8 -8
- package/docs/Reference/Request.md +1 -1
- package/docs/Reference/Routes.md +3 -3
- package/docs/Reference/Server.md +35 -21
- package/docs/Reference/Validation-and-Serialization.md +1 -1
- package/fastify.d.ts +2 -1
- package/fastify.js +14 -2
- package/lib/configValidator.js +1 -1
- package/lib/errors.js +6 -0
- package/lib/pluginOverride.js +3 -1
- package/lib/reply.js +7 -11
- package/lib/request.js +3 -10
- package/lib/symbols.js +1 -0
- package/lib/warnings.js +8 -0
- package/package.json +8 -4
- package/test/404s.test.js +226 -325
- package/test/allow-unsafe-regex.test.js +19 -48
- package/test/als.test.js +28 -40
- package/test/async-await.test.js +11 -2
- package/test/body-limit.test.js +41 -65
- package/test/build-certificate.js +1 -1
- package/test/custom-parser-async.test.js +17 -22
- package/test/decorator-namespace.test._js_ +3 -4
- package/test/diagnostics-channel/async-delay-request.test.js +7 -16
- package/test/diagnostics-channel/sync-delay-request.test.js +7 -16
- package/test/helper.js +1 -1
- package/test/hooks-async.test.js +248 -218
- package/test/hooks.test.js +910 -769
- package/test/http-methods/lock.test.js +31 -31
- package/test/http-methods/mkcol.test.js +5 -9
- package/test/http-methods/proppatch.test.js +23 -29
- package/test/http-methods/report.test.js +44 -69
- package/test/http-methods/search.test.js +67 -82
- package/test/http2/closing.test.js +38 -20
- package/test/http2/secure-with-fallback.test.js +28 -27
- package/test/https/https.test.js +56 -53
- package/test/internals/errors.test.js +1 -1
- package/test/internals/handle-request.test.js +49 -66
- package/test/issue-4959.test.js +12 -3
- package/test/listen.4.test.js +31 -43
- package/test/nullable-validation.test.js +33 -46
- package/test/output-validation.test.js +24 -26
- package/test/plugin.2.test.js +104 -86
- package/test/plugin.3.test.js +56 -35
- package/test/plugin.4.test.js +124 -119
- package/test/proto-poisoning.test.js +78 -97
- package/test/request-error.test.js +0 -46
- package/test/route-hooks.test.js +112 -92
- package/test/route-prefix.test.js +194 -133
- package/test/schema-serialization.test.js +177 -154
- package/test/schema-special-usage.test.js +165 -132
- package/test/schema-validation.test.js +242 -205
- package/test/set-error-handler.test.js +58 -1
- package/test/skip-reply-send.test.js +64 -69
- package/test/trust-proxy.test.js +32 -58
- package/test/types/fastify.test-d.ts +3 -0
- package/test/types/request.test-d.ts +1 -0
- package/test/url-rewriting.test.js +45 -62
- package/types/request.d.ts +1 -0
- package/.taprc +0 -7
- package/.vscode/settings.json +0 -22
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
4
|
const Fastify = require('../..')
|
|
5
5
|
const h2url = require('h2url')
|
|
6
|
-
const sget = require('simple-get').concat
|
|
7
6
|
const msg = { hello: 'world' }
|
|
8
7
|
|
|
9
8
|
const { buildCertificate } = require('../build-certificate')
|
|
9
|
+
const { Agent } = require('undici')
|
|
10
10
|
test.before(buildCertificate)
|
|
11
11
|
|
|
12
12
|
test('secure with fallback', async (t) => {
|
|
@@ -41,12 +41,12 @@ test('secure with fallback', async (t) => {
|
|
|
41
41
|
|
|
42
42
|
t.after(() => { fastify.close() })
|
|
43
43
|
|
|
44
|
-
await fastify.listen({ port: 0 })
|
|
44
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
45
45
|
|
|
46
46
|
await t.test('https get error', async (t) => {
|
|
47
47
|
t.plan(1)
|
|
48
48
|
|
|
49
|
-
const url =
|
|
49
|
+
const url = `${fastifyServer}/error`
|
|
50
50
|
const res = await h2url.concat({ url })
|
|
51
51
|
|
|
52
52
|
t.assert.strictEqual(res.headers[':status'], 500)
|
|
@@ -55,9 +55,8 @@ test('secure with fallback', async (t) => {
|
|
|
55
55
|
await t.test('https post', async (t) => {
|
|
56
56
|
t.plan(2)
|
|
57
57
|
|
|
58
|
-
const url = `https://localhost:${fastify.server.address().port}`
|
|
59
58
|
const res = await h2url.concat({
|
|
60
|
-
url,
|
|
59
|
+
url: fastifyServer,
|
|
61
60
|
method: 'POST',
|
|
62
61
|
body: JSON.stringify({ hello: 'http2' }),
|
|
63
62
|
headers: {
|
|
@@ -72,39 +71,41 @@ test('secure with fallback', async (t) => {
|
|
|
72
71
|
await t.test('https get request', async (t) => {
|
|
73
72
|
t.plan(3)
|
|
74
73
|
|
|
75
|
-
const
|
|
76
|
-
const res = await h2url.concat({ url })
|
|
74
|
+
const res = await h2url.concat({ url: fastifyServer })
|
|
77
75
|
|
|
78
76
|
t.assert.strictEqual(res.headers[':status'], 200)
|
|
79
77
|
t.assert.strictEqual(res.headers['content-length'], '' + JSON.stringify(msg).length)
|
|
80
78
|
t.assert.deepStrictEqual(JSON.parse(res.body), msg)
|
|
81
79
|
})
|
|
82
80
|
|
|
83
|
-
await t.test('http1 get request',
|
|
81
|
+
await t.test('http1 get request', async t => {
|
|
84
82
|
t.plan(4)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
t.assert.strictEqual(response.statusCode, 200)
|
|
92
|
-
t.assert.strictEqual(response.headers['content-length'], '' + body.length)
|
|
93
|
-
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
|
94
|
-
done()
|
|
83
|
+
const result = await fetch(fastifyServer, {
|
|
84
|
+
dispatcher: new Agent({
|
|
85
|
+
connect: {
|
|
86
|
+
rejectUnauthorized: false
|
|
87
|
+
}
|
|
88
|
+
})
|
|
95
89
|
})
|
|
90
|
+
|
|
91
|
+
const body = await result.text()
|
|
92
|
+
t.assert.ok(result.ok)
|
|
93
|
+
t.assert.strictEqual(result.status, 200)
|
|
94
|
+
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
|
95
|
+
t.assert.deepStrictEqual(JSON.parse(body), msg)
|
|
96
96
|
})
|
|
97
97
|
|
|
98
|
-
await t.test('http1 get error',
|
|
98
|
+
await t.test('http1 get error', async t => {
|
|
99
99
|
t.plan(2)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
t.assert.strictEqual(response.statusCode, 500)
|
|
107
|
-
done()
|
|
100
|
+
const result = await fetch(`${fastifyServer}/error`, {
|
|
101
|
+
dispatcher: new Agent({
|
|
102
|
+
connect: {
|
|
103
|
+
rejectUnauthorized: false
|
|
104
|
+
}
|
|
105
|
+
})
|
|
108
106
|
})
|
|
107
|
+
|
|
108
|
+
t.assert.ok(!result.ok)
|
|
109
|
+
t.assert.strictEqual(result.status, 500)
|
|
109
110
|
})
|
|
110
111
|
})
|
package/test/https/https.test.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
|
-
const
|
|
4
|
+
const { request } = require('undici')
|
|
5
5
|
const Fastify = require('../..')
|
|
6
6
|
|
|
7
7
|
const { buildCertificate } = require('../build-certificate')
|
|
8
|
+
const { Agent } = require('undici')
|
|
8
9
|
test.before(buildCertificate)
|
|
9
10
|
|
|
10
11
|
test('https', async (t) => {
|
|
@@ -35,43 +36,45 @@ test('https', async (t) => {
|
|
|
35
36
|
|
|
36
37
|
t.after(() => { fastify.close() })
|
|
37
38
|
|
|
38
|
-
await t.test('https get request',
|
|
39
|
+
await t.test('https get request', async t => {
|
|
39
40
|
t.plan(4)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
t.assert.strictEqual(response.statusCode, 200)
|
|
47
|
-
t.assert.strictEqual(response.headers['content-length'], '' + body.length)
|
|
48
|
-
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
|
49
|
-
done()
|
|
41
|
+
const result = await fetch('https://localhost:' + fastify.server.address().port, {
|
|
42
|
+
dispatcher: new Agent({
|
|
43
|
+
connect: {
|
|
44
|
+
rejectUnauthorized: false
|
|
45
|
+
}
|
|
46
|
+
})
|
|
50
47
|
})
|
|
48
|
+
t.assert.ok(result.ok)
|
|
49
|
+
t.assert.strictEqual(result.status, 200)
|
|
50
|
+
const body = await result.text()
|
|
51
|
+
t.assert.strictEqual(result.headers.get('content-length'), '' + body.length)
|
|
52
|
+
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
|
51
53
|
})
|
|
52
54
|
|
|
53
|
-
await t.test('https get request without trust proxy - protocol',
|
|
54
|
-
t.plan(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
t.assert.deepStrictEqual(JSON.parse(body), { proto: 'https' })
|
|
55
|
+
await t.test('https get request without trust proxy - protocol', async t => {
|
|
56
|
+
t.plan(3)
|
|
57
|
+
const result1 = await fetch(`${'https://localhost:' + fastify.server.address().port}/proto`, {
|
|
58
|
+
dispatcher: new Agent({
|
|
59
|
+
connect: {
|
|
60
|
+
rejectUnauthorized: false
|
|
61
|
+
}
|
|
62
|
+
})
|
|
62
63
|
})
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
t.assert.ok(result1.ok)
|
|
65
|
+
t.assert.deepStrictEqual(await result1.json(), { proto: 'https' })
|
|
66
|
+
|
|
67
|
+
const result2 = await fetch(`${'https://localhost:' + fastify.server.address().port}/proto`, {
|
|
68
|
+
dispatcher: new Agent({
|
|
69
|
+
connect: {
|
|
70
|
+
rejectUnauthorized: false
|
|
71
|
+
}
|
|
72
|
+
}),
|
|
67
73
|
headers: {
|
|
68
74
|
'x-forwarded-proto': 'lorem'
|
|
69
75
|
}
|
|
70
|
-
}, (err, response, body) => {
|
|
71
|
-
t.assert.ifError(err)
|
|
72
|
-
t.assert.deepStrictEqual(JSON.parse(body), { proto: 'https' })
|
|
73
|
-
done()
|
|
74
76
|
})
|
|
77
|
+
t.assert.deepStrictEqual(await result2.json(), { proto: 'https' })
|
|
75
78
|
})
|
|
76
79
|
})
|
|
77
80
|
|
|
@@ -98,36 +101,36 @@ test('https - headers', async (t) => {
|
|
|
98
101
|
|
|
99
102
|
await fastify.listen({ port: 0 })
|
|
100
103
|
|
|
101
|
-
await t.test('https get request',
|
|
102
|
-
t.plan(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
t.assert.strictEqual(response.statusCode, 200)
|
|
110
|
-
const parsedBody = JSON.parse(body)
|
|
111
|
-
t.assert.strictEqual(parsedBody.hostname, 'localhost')
|
|
112
|
-
t.assert.strictEqual(parsedBody.port, fastify.server.address().port)
|
|
113
|
-
done()
|
|
104
|
+
await t.test('https get request', async t => {
|
|
105
|
+
t.plan(3)
|
|
106
|
+
const result = await fetch('https://localhost:' + fastify.server.address().port, {
|
|
107
|
+
dispatcher: new Agent({
|
|
108
|
+
connect: {
|
|
109
|
+
rejectUnauthorized: false
|
|
110
|
+
}
|
|
111
|
+
})
|
|
114
112
|
})
|
|
113
|
+
t.assert.ok(result.ok)
|
|
114
|
+
t.assert.strictEqual(result.status, 200)
|
|
115
|
+
t.assert.deepStrictEqual(await result.json(), { hostname: 'localhost', port: fastify.server.address().port, hello: 'world' })
|
|
115
116
|
})
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
|
|
118
|
+
await t.test('https get request - test port fall back', async t => {
|
|
119
|
+
t.plan(2)
|
|
120
|
+
|
|
121
|
+
const result = await request('https://localhost:' + fastify.server.address().port, {
|
|
119
122
|
method: 'GET',
|
|
120
123
|
headers: {
|
|
121
124
|
host: 'example.com'
|
|
122
125
|
},
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const parsedBody = JSON.parse(body)
|
|
129
|
-
t.assert.strictEqual(parsedBody.port, null)
|
|
130
|
-
done()
|
|
126
|
+
dispatcher: new Agent({
|
|
127
|
+
connect: {
|
|
128
|
+
rejectUnauthorized: false
|
|
129
|
+
}
|
|
130
|
+
})
|
|
131
131
|
})
|
|
132
|
+
|
|
133
|
+
t.assert.strictEqual(result.statusCode, 200)
|
|
134
|
+
t.assert.deepStrictEqual(await result.body.json(), { hello: 'world', hostname: 'example.com', port: null })
|
|
132
135
|
})
|
|
133
136
|
})
|
|
@@ -7,7 +7,6 @@ const Request = require('../../lib/request')
|
|
|
7
7
|
const Reply = require('../../lib/reply')
|
|
8
8
|
const { kRouteContext } = require('../../lib/symbols')
|
|
9
9
|
const buildSchema = require('../../lib/validation').compileSchemasForValidation
|
|
10
|
-
const sget = require('simple-get').concat
|
|
11
10
|
|
|
12
11
|
const Ajv = require('ajv')
|
|
13
12
|
const ajv = new Ajv({ coerceTypes: true })
|
|
@@ -129,8 +128,8 @@ test('handler function - preValidationCallback with finished response', t => {
|
|
|
129
128
|
internals.handler({ [kRouteContext]: context }, new Reply(res, { [kRouteContext]: context }))
|
|
130
129
|
})
|
|
131
130
|
|
|
132
|
-
test('request should be defined in onSend Hook on post request with content type application/json',
|
|
133
|
-
t.plan(
|
|
131
|
+
test('request should be defined in onSend Hook on post request with content type application/json', async t => {
|
|
132
|
+
t.plan(6)
|
|
134
133
|
const fastify = require('../..')()
|
|
135
134
|
|
|
136
135
|
t.after(() => {
|
|
@@ -149,28 +148,24 @@ test('request should be defined in onSend Hook on post request with content type
|
|
|
149
148
|
reply.send(200)
|
|
150
149
|
})
|
|
151
150
|
|
|
152
|
-
fastify.listen({ port: 0 }
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
'content-type': 'application/json'
|
|
159
|
-
}
|
|
160
|
-
}, (err, response, body) => {
|
|
161
|
-
t.assert.ifError(err)
|
|
162
|
-
// a 400 error is expected because of no body
|
|
163
|
-
t.assert.strictEqual(response.statusCode, 400)
|
|
164
|
-
done()
|
|
165
|
-
})
|
|
151
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
152
|
+
const result = await fetch(fastifyServer, {
|
|
153
|
+
method: 'POST',
|
|
154
|
+
headers: {
|
|
155
|
+
'content-type': 'application/json'
|
|
156
|
+
}
|
|
166
157
|
})
|
|
158
|
+
|
|
159
|
+
t.assert.strictEqual(result.status, 400)
|
|
167
160
|
})
|
|
168
161
|
|
|
169
|
-
test('request should be defined in onSend Hook on post request with content type application/x-www-form-urlencoded',
|
|
170
|
-
t.plan(
|
|
162
|
+
test('request should be defined in onSend Hook on post request with content type application/x-www-form-urlencoded', async t => {
|
|
163
|
+
t.plan(5)
|
|
171
164
|
const fastify = require('../..')()
|
|
172
165
|
|
|
173
|
-
t.after(() => {
|
|
166
|
+
t.after(() => {
|
|
167
|
+
fastify.close()
|
|
168
|
+
})
|
|
174
169
|
|
|
175
170
|
fastify.addHook('onSend', (request, reply, payload, done) => {
|
|
176
171
|
t.assert.ok(request)
|
|
@@ -183,29 +178,25 @@ test('request should be defined in onSend Hook on post request with content type
|
|
|
183
178
|
reply.send(200)
|
|
184
179
|
})
|
|
185
180
|
|
|
186
|
-
fastify.listen({ port: 0 }
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
headers: {
|
|
193
|
-
'content-type': 'application/x-www-form-urlencoded'
|
|
194
|
-
}
|
|
195
|
-
}, (err, response, body) => {
|
|
196
|
-
t.assert.ifError(err)
|
|
197
|
-
// a 415 error is expected because of missing content type parser
|
|
198
|
-
t.assert.strictEqual(response.statusCode, 415)
|
|
199
|
-
done()
|
|
200
|
-
})
|
|
181
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
182
|
+
const result = await fetch(fastifyServer, {
|
|
183
|
+
method: 'POST',
|
|
184
|
+
headers: {
|
|
185
|
+
'content-type': 'application/x-www-form-urlencoded'
|
|
186
|
+
}
|
|
201
187
|
})
|
|
188
|
+
|
|
189
|
+
// a 415 error is expected because of missing content type parser
|
|
190
|
+
t.assert.strictEqual(result.status, 415)
|
|
202
191
|
})
|
|
203
192
|
|
|
204
|
-
test('request should be defined in onSend Hook on options request with content type application/x-www-form-urlencoded',
|
|
205
|
-
t.plan(
|
|
193
|
+
test('request should be defined in onSend Hook on options request with content type application/x-www-form-urlencoded', async t => {
|
|
194
|
+
t.plan(5)
|
|
206
195
|
const fastify = require('../..')()
|
|
207
196
|
|
|
208
|
-
t.after(() => {
|
|
197
|
+
t.after(() => {
|
|
198
|
+
fastify.close()
|
|
199
|
+
})
|
|
209
200
|
|
|
210
201
|
fastify.addHook('onSend', (request, reply, payload, done) => {
|
|
211
202
|
t.assert.ok(request)
|
|
@@ -218,26 +209,20 @@ test('request should be defined in onSend Hook on options request with content t
|
|
|
218
209
|
reply.send(200)
|
|
219
210
|
})
|
|
220
211
|
|
|
221
|
-
fastify.listen({ port: 0 }
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
headers: {
|
|
228
|
-
'content-type': 'application/x-www-form-urlencoded'
|
|
229
|
-
}
|
|
230
|
-
}, (err, response, body) => {
|
|
231
|
-
t.assert.ifError(err)
|
|
232
|
-
// Body parsing skipped, so no body sent
|
|
233
|
-
t.assert.strictEqual(response.statusCode, 200)
|
|
234
|
-
done()
|
|
235
|
-
})
|
|
212
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
213
|
+
const result = await fetch(fastifyServer, {
|
|
214
|
+
method: 'OPTIONS',
|
|
215
|
+
headers: {
|
|
216
|
+
'content-type': 'application/x-www-form-urlencoded'
|
|
217
|
+
}
|
|
236
218
|
})
|
|
219
|
+
|
|
220
|
+
// Body parsing skipped, so no body sent
|
|
221
|
+
t.assert.strictEqual(result.status, 200)
|
|
237
222
|
})
|
|
238
223
|
|
|
239
|
-
test('request should respond with an error if an unserialized payload is sent inside an async handler',
|
|
240
|
-
t.plan(
|
|
224
|
+
test('request should respond with an error if an unserialized payload is sent inside an async handler', async t => {
|
|
225
|
+
t.plan(2)
|
|
241
226
|
|
|
242
227
|
const fastify = require('../..')()
|
|
243
228
|
|
|
@@ -246,18 +231,16 @@ test('request should respond with an error if an unserialized payload is sent in
|
|
|
246
231
|
return Promise.resolve(request.headers)
|
|
247
232
|
})
|
|
248
233
|
|
|
249
|
-
fastify.inject({
|
|
234
|
+
const res = await fastify.inject({
|
|
250
235
|
method: 'GET',
|
|
251
236
|
url: '/'
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
})
|
|
261
|
-
done()
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
t.assert.strictEqual(res.statusCode, 500)
|
|
240
|
+
t.assert.deepStrictEqual(JSON.parse(res.payload), {
|
|
241
|
+
error: 'Internal Server Error',
|
|
242
|
+
code: 'FST_ERR_REP_INVALID_PAYLOAD_TYPE',
|
|
243
|
+
message: 'Attempted to send payload of invalid type \'object\'. Expected a string or Buffer.',
|
|
244
|
+
statusCode: 500
|
|
262
245
|
})
|
|
263
246
|
})
|
package/test/issue-4959.test.js
CHANGED
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
4
|
const http = require('node:http')
|
|
5
5
|
const Fastify = require('../fastify')
|
|
6
|
-
|
|
6
|
+
const { setTimeout } = require('node:timers')
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* Ensure that a socket error during the request does not cause the
|
|
10
|
+
* onSend hook to be called multiple times.
|
|
11
|
+
*
|
|
12
|
+
* @see https://github.com/fastify/fastify/issues/4959
|
|
13
|
+
*/
|
|
7
14
|
function runBadClientCall (reqOptions, payload) {
|
|
8
15
|
let innerResolve, innerReject
|
|
9
16
|
const promise = new Promise((resolve, reject) => {
|
|
@@ -25,7 +32,9 @@ function runBadClientCall (reqOptions, payload) {
|
|
|
25
32
|
|
|
26
33
|
// Kill the socket immediately (before sending data)
|
|
27
34
|
req.on('socket', (socket) => {
|
|
28
|
-
|
|
35
|
+
socket.on('connect', () => {
|
|
36
|
+
setTimeout(() => { socket.destroy() }, 0)
|
|
37
|
+
})
|
|
29
38
|
})
|
|
30
39
|
req.on('error', innerResolve)
|
|
31
40
|
req.write(postData)
|
|
@@ -34,7 +43,7 @@ function runBadClientCall (reqOptions, payload) {
|
|
|
34
43
|
return promise
|
|
35
44
|
}
|
|
36
45
|
|
|
37
|
-
test('should handle a
|
|
46
|
+
test('should handle a socket error', async (t) => {
|
|
38
47
|
t.plan(4)
|
|
39
48
|
const fastify = Fastify()
|
|
40
49
|
|
package/test/listen.4.test.js
CHANGED
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
const { test, before } = require('node:test')
|
|
4
4
|
const dns = require('node:dns').promises
|
|
5
5
|
const dnsCb = require('node:dns')
|
|
6
|
-
const sget = require('simple-get').concat
|
|
7
6
|
const Fastify = require('../fastify')
|
|
8
7
|
const helper = require('./helper')
|
|
9
|
-
const { waitForCb } = require('./toolkit')
|
|
10
8
|
|
|
11
9
|
let localhostForURL
|
|
12
10
|
|
|
@@ -90,7 +88,7 @@ test('listen logs the port as info', async t => {
|
|
|
90
88
|
|
|
91
89
|
test('listen on localhost binds IPv4 and IPv6 - promise interface', async t => {
|
|
92
90
|
const localAddresses = await dns.lookup('localhost', { all: true })
|
|
93
|
-
t.plan(
|
|
91
|
+
t.plan(3 * localAddresses.length)
|
|
94
92
|
|
|
95
93
|
const app = Fastify()
|
|
96
94
|
app.get('/', async () => 'hello localhost')
|
|
@@ -98,52 +96,42 @@ test('listen on localhost binds IPv4 and IPv6 - promise interface', async t => {
|
|
|
98
96
|
await app.listen({ port: 0, host: 'localhost' })
|
|
99
97
|
|
|
100
98
|
for (const lookup of localAddresses) {
|
|
101
|
-
await
|
|
102
|
-
|
|
103
|
-
method: 'GET',
|
|
104
|
-
url: getUrl(app, lookup)
|
|
105
|
-
}, (err, response, body) => {
|
|
106
|
-
if (err) { return reject(err) }
|
|
107
|
-
t.assert.strictEqual(response.statusCode, 200)
|
|
108
|
-
t.assert.deepStrictEqual(body.toString(), 'hello localhost')
|
|
109
|
-
resolve()
|
|
110
|
-
})
|
|
99
|
+
const result = await fetch(getUrl(app, lookup), {
|
|
100
|
+
method: 'GET'
|
|
111
101
|
})
|
|
102
|
+
|
|
103
|
+
t.assert.ok(result.ok)
|
|
104
|
+
t.assert.deepEqual(result.status, 200)
|
|
105
|
+
t.assert.deepStrictEqual(await result.text(), 'hello localhost')
|
|
112
106
|
}
|
|
113
107
|
})
|
|
114
108
|
|
|
115
|
-
test('listen on localhost binds to all interfaces (both IPv4 and IPv6 if present) - callback interface', (t
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const app = Fastify()
|
|
121
|
-
app.get('/', async () => 'hello localhost')
|
|
122
|
-
app.listen({ port: 0, host: 'localhost' }, (err) => {
|
|
123
|
-
t.assert.ifError(err)
|
|
124
|
-
t.after(() => app.close())
|
|
125
|
-
|
|
126
|
-
const { stepIn, patience } = waitForCb({ steps: lookups.length })
|
|
127
|
-
|
|
128
|
-
// Loop over each lookup and perform the assertions
|
|
129
|
-
if (lookups.length > 0) {
|
|
130
|
-
for (const lookup of lookups) {
|
|
131
|
-
sget({
|
|
132
|
-
method: 'GET',
|
|
133
|
-
url: getUrl(app, lookup)
|
|
134
|
-
}, (err, response, body) => {
|
|
135
|
-
t.assert.ifError(err)
|
|
136
|
-
t.assert.strictEqual(response.statusCode, 200)
|
|
137
|
-
t.assert.deepStrictEqual(body.toString(), 'hello localhost')
|
|
138
|
-
// Call stepIn to report that a request has been completed
|
|
139
|
-
stepIn()
|
|
140
|
-
})
|
|
141
|
-
}
|
|
142
|
-
// When all requests have been completed, call done
|
|
143
|
-
patience.then(() => done())
|
|
144
|
-
}
|
|
109
|
+
test('listen on localhost binds to all interfaces (both IPv4 and IPv6 if present) - callback interface', async (t) => {
|
|
110
|
+
const lookups = await new Promise((resolve, reject) => {
|
|
111
|
+
dnsCb.lookup('localhost', { all: true }, (err, lookups) => {
|
|
112
|
+
if (err) return reject(err)
|
|
113
|
+
resolve(lookups)
|
|
145
114
|
})
|
|
146
115
|
})
|
|
116
|
+
|
|
117
|
+
t.plan(3 * lookups.length)
|
|
118
|
+
|
|
119
|
+
const app = Fastify()
|
|
120
|
+
app.get('/', async () => 'hello localhost')
|
|
121
|
+
t.after(() => app.close())
|
|
122
|
+
|
|
123
|
+
await app.listen({ port: 0, host: 'localhost' })
|
|
124
|
+
|
|
125
|
+
// Loop over each lookup and perform the assertions
|
|
126
|
+
for (const lookup of lookups) {
|
|
127
|
+
const result = await fetch(getUrl(app, lookup), {
|
|
128
|
+
method: 'GET'
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
t.assert.ok(result.ok)
|
|
132
|
+
t.assert.deepEqual(result.status, 200)
|
|
133
|
+
t.assert.deepStrictEqual(await result.text(), 'hello localhost')
|
|
134
|
+
}
|
|
147
135
|
})
|
|
148
136
|
|
|
149
137
|
test('addresses getter', async t => {
|