fastify 5.4.0 → 5.5.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/.vscode/settings.json +22 -0
- package/LICENSE +1 -1
- package/SECURITY.md +158 -2
- package/build/build-validation.js +19 -1
- package/docs/Guides/Delay-Accepting-Requests.md +8 -5
- package/docs/Guides/Ecosystem.md +11 -0
- package/docs/Guides/Migration-Guide-V5.md +6 -10
- package/docs/Guides/Recommendations.md +1 -1
- package/docs/Reference/Errors.md +3 -1
- package/docs/Reference/Hooks.md +2 -6
- package/docs/Reference/Lifecycle.md +2 -2
- package/docs/Reference/Request.md +1 -1
- package/docs/Reference/Routes.md +4 -3
- package/docs/Reference/Server.md +306 -179
- package/docs/Reference/TypeScript.md +1 -3
- package/docs/Reference/Validation-and-Serialization.md +55 -3
- package/docs/Reference/Warnings.md +2 -1
- package/fastify.d.ts +2 -2
- package/fastify.js +34 -33
- package/lib/configValidator.js +196 -28
- package/lib/contentTypeParser.js +41 -48
- package/lib/error-handler.js +3 -3
- package/lib/errors.js +5 -0
- package/lib/handleRequest.js +13 -17
- package/lib/promise.js +23 -0
- package/lib/reply.js +17 -19
- package/lib/route.js +37 -3
- package/lib/server.js +36 -35
- package/lib/warnings.js +11 -1
- package/package.json +7 -7
- package/test/async-await.test.js +81 -134
- package/test/async_hooks.test.js +18 -37
- package/test/body-limit.test.js +51 -0
- package/test/buffer.test.js +22 -0
- package/test/case-insensitive.test.js +44 -65
- package/test/check.test.js +17 -21
- package/test/close-pipelining.test.js +24 -15
- package/test/constrained-routes.test.js +231 -0
- package/test/custom-http-server.test.js +7 -15
- package/test/custom-parser.0.test.js +267 -348
- package/test/custom-parser.1.test.js +141 -191
- package/test/custom-parser.2.test.js +34 -44
- package/test/custom-parser.3.test.js +56 -104
- package/test/custom-parser.4.test.js +106 -144
- package/test/custom-parser.5.test.js +56 -75
- package/test/custom-querystring-parser.test.js +51 -77
- package/test/decorator.test.js +76 -259
- package/test/delete.test.js +101 -110
- package/test/diagnostics-channel/404.test.js +7 -15
- package/test/diagnostics-channel/async-request.test.js +8 -16
- package/test/diagnostics-channel/error-request.test.js +7 -15
- package/test/diagnostics-channel/sync-request-reply.test.js +9 -16
- package/test/diagnostics-channel/sync-request.test.js +9 -16
- package/test/fastify-instance.test.js +1 -1
- package/test/header-overflow.test.js +18 -29
- package/test/helper.js +138 -134
- package/test/hooks-async.test.js +26 -32
- package/test/hooks.test.js +261 -447
- package/test/http-methods/copy.test.js +14 -19
- package/test/http-methods/get.test.js +131 -143
- package/test/http-methods/head.test.js +53 -84
- package/test/http-methods/mkcalendar.test.js +45 -72
- package/test/http-methods/move.test.js +6 -10
- package/test/http-methods/propfind.test.js +34 -44
- package/test/http-methods/unlock.test.js +5 -9
- package/test/http2/secure-with-fallback.test.js +3 -1
- package/test/https/custom-https-server.test.js +9 -13
- package/test/input-validation.js +139 -150
- package/test/internals/errors.test.js +50 -1
- package/test/internals/handle-request.test.js +29 -5
- package/test/internals/promise.test.js +63 -0
- package/test/internals/reply.test.js +277 -496
- package/test/plugin.1.test.js +40 -68
- package/test/plugin.2.test.js +40 -70
- package/test/plugin.3.test.js +25 -68
- package/test/promises.test.js +42 -63
- package/test/register.test.js +8 -18
- package/test/request-error.test.js +57 -100
- package/test/request-id.test.js +30 -49
- package/test/route-hooks.test.js +12 -16
- package/test/route-shorthand.test.js +9 -27
- package/test/route.1.test.js +74 -131
- package/test/route.8.test.js +9 -17
- package/test/router-options.test.js +450 -0
- package/test/schema-validation.test.js +30 -31
- package/test/server.test.js +143 -5
- package/test/stream.1.test.js +33 -50
- package/test/stream.4.test.js +18 -28
- package/test/stream.5.test.js +11 -19
- package/test/types/errors.test-d.ts +13 -1
- package/test/types/type-provider.test-d.ts +55 -0
- package/test/use-semicolon-delimiter.test.js +117 -59
- package/test/versioned-routes.test.js +39 -56
- package/types/errors.d.ts +11 -1
- package/types/hooks.d.ts +1 -1
- package/types/instance.d.ts +1 -1
- package/types/reply.d.ts +2 -2
package/test/check.test.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
4
|
const { S } = require('fluent-json-schema')
|
|
5
5
|
const Fastify = require('..')
|
|
6
|
-
const sget = require('simple-get').concat
|
|
7
6
|
|
|
8
7
|
const BadRequestSchema = S.object()
|
|
9
8
|
.prop('statusCode', S.number())
|
|
@@ -105,32 +104,29 @@ const handler = (request, reply) => {
|
|
|
105
104
|
})
|
|
106
105
|
}
|
|
107
106
|
|
|
108
|
-
test('serialize the response for a Bad Request error, as defined on the schema',
|
|
107
|
+
test('serialize the response for a Bad Request error, as defined on the schema', async t => {
|
|
109
108
|
const fastify = Fastify({})
|
|
110
109
|
|
|
111
110
|
t.after(() => fastify.close())
|
|
112
111
|
|
|
113
112
|
fastify.post('/', options, handler)
|
|
114
113
|
|
|
115
|
-
fastify.listen({ port: 0 }
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
})
|
|
132
|
-
done()
|
|
133
|
-
})
|
|
114
|
+
const fastifyServer = await fastify.listen({ port: 0 })
|
|
115
|
+
|
|
116
|
+
const result = await fetch(fastifyServer, {
|
|
117
|
+
method: 'POST',
|
|
118
|
+
headers: {
|
|
119
|
+
'Content-Type': 'application/json'
|
|
120
|
+
},
|
|
121
|
+
body: '12'
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
t.assert.ok(!result.ok)
|
|
125
|
+
t.assert.strictEqual(result.status, 400)
|
|
126
|
+
t.assert.deepStrictEqual(await result.json(), {
|
|
127
|
+
statusCode: 400,
|
|
128
|
+
error: 'Bad Request',
|
|
129
|
+
message: 'body must be object'
|
|
134
130
|
})
|
|
135
131
|
})
|
|
136
132
|
|
|
@@ -11,8 +11,10 @@ test('Should return 503 while closing - pipelining', async t => {
|
|
|
11
11
|
})
|
|
12
12
|
|
|
13
13
|
fastify.get('/', async (req, reply) => {
|
|
14
|
+
// Simulate a delay to allow pipelining to kick in
|
|
15
|
+
await new Promise(resolve => setTimeout(resolve, 5))
|
|
16
|
+
reply.send({ hello: 'world' })
|
|
14
17
|
fastify.close()
|
|
15
|
-
return { hello: 'world' }
|
|
16
18
|
})
|
|
17
19
|
|
|
18
20
|
await fastify.listen({ port: 0 })
|
|
@@ -21,14 +23,19 @@ test('Should return 503 while closing - pipelining', async t => {
|
|
|
21
23
|
pipelining: 2
|
|
22
24
|
})
|
|
23
25
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
instance.request({ path: '/', method: 'GET' }),
|
|
27
|
-
instance.request({ path: '/', method: 'GET' })
|
|
28
|
-
instance.request({ path: '/', method: 'GET' })
|
|
26
|
+
const [firstRequest, secondRequest, thirdRequest] = await Promise.allSettled([
|
|
27
|
+
instance.request({ path: '/', method: 'GET', blocking: false }),
|
|
28
|
+
instance.request({ path: '/', method: 'GET', blocking: false }),
|
|
29
|
+
instance.request({ path: '/', method: 'GET', blocking: false })
|
|
29
30
|
])
|
|
30
|
-
|
|
31
|
-
t.assert.
|
|
31
|
+
t.assert.strictEqual(firstRequest.status, 'fulfilled')
|
|
32
|
+
t.assert.strictEqual(secondRequest.status, 'fulfilled')
|
|
33
|
+
|
|
34
|
+
t.assert.strictEqual(firstRequest.value.statusCode, 200)
|
|
35
|
+
t.assert.strictEqual(secondRequest.value.statusCode, 200)
|
|
36
|
+
|
|
37
|
+
t.assert.strictEqual(thirdRequest.status, 'fulfilled')
|
|
38
|
+
t.assert.strictEqual(thirdRequest.value.statusCode, 503)
|
|
32
39
|
|
|
33
40
|
await instance.close()
|
|
34
41
|
})
|
|
@@ -42,6 +49,8 @@ test('Should close the socket abruptly - pipelining - return503OnClosing: false'
|
|
|
42
49
|
})
|
|
43
50
|
|
|
44
51
|
fastify.get('/', async (req, reply) => {
|
|
52
|
+
// Simulate a delay to allow pipelining to kick in
|
|
53
|
+
await new Promise(resolve => setTimeout(resolve, 5))
|
|
45
54
|
reply.send({ hello: 'world' })
|
|
46
55
|
fastify.close()
|
|
47
56
|
})
|
|
@@ -49,21 +58,21 @@ test('Should close the socket abruptly - pipelining - return503OnClosing: false'
|
|
|
49
58
|
await fastify.listen({ port: 0 })
|
|
50
59
|
|
|
51
60
|
const instance = new Client('http://localhost:' + fastify.server.address().port, {
|
|
52
|
-
pipelining:
|
|
61
|
+
pipelining: 1
|
|
53
62
|
})
|
|
54
63
|
|
|
55
64
|
const responses = await Promise.allSettled([
|
|
56
|
-
instance.request({ path: '/', method: 'GET' }),
|
|
57
|
-
instance.request({ path: '/', method: 'GET' }),
|
|
58
|
-
instance.request({ path: '/', method: 'GET' }),
|
|
59
|
-
instance.request({ path: '/', method: 'GET' })
|
|
65
|
+
instance.request({ path: '/', method: 'GET', blocking: false }),
|
|
66
|
+
instance.request({ path: '/', method: 'GET', blocking: false }),
|
|
67
|
+
instance.request({ path: '/', method: 'GET', blocking: false }),
|
|
68
|
+
instance.request({ path: '/', method: 'GET', blocking: false })
|
|
60
69
|
])
|
|
61
70
|
|
|
62
71
|
const fulfilled = responses.filter(r => r.status === 'fulfilled')
|
|
63
72
|
const rejected = responses.filter(r => r.status === 'rejected')
|
|
64
73
|
|
|
65
|
-
t.assert.strictEqual(fulfilled.length,
|
|
66
|
-
t.assert.strictEqual(rejected.length,
|
|
74
|
+
t.assert.strictEqual(fulfilled.length, 1)
|
|
75
|
+
t.assert.strictEqual(rejected.length, 3)
|
|
67
76
|
|
|
68
77
|
await instance.close()
|
|
69
78
|
})
|
|
@@ -905,3 +905,234 @@ test('Allow regex constraints in routes', async t => {
|
|
|
905
905
|
t.assert.strictEqual(res.statusCode, 404)
|
|
906
906
|
}
|
|
907
907
|
})
|
|
908
|
+
|
|
909
|
+
test('Should allow registering custom rotuerOptions constrained routes', async t => {
|
|
910
|
+
t.plan(5)
|
|
911
|
+
|
|
912
|
+
const constraint = {
|
|
913
|
+
name: 'secret',
|
|
914
|
+
storage: function () {
|
|
915
|
+
const secrets = {}
|
|
916
|
+
return {
|
|
917
|
+
get: (secret) => { return secrets[secret] || null },
|
|
918
|
+
set: (secret, store) => { secrets[secret] = store }
|
|
919
|
+
}
|
|
920
|
+
},
|
|
921
|
+
deriveConstraint: (req, ctx) => {
|
|
922
|
+
return req.headers['x-secret']
|
|
923
|
+
},
|
|
924
|
+
validate () { return true }
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
const fastify = Fastify({ routerOptions: { constraints: { secret: constraint } } })
|
|
928
|
+
|
|
929
|
+
fastify.route({
|
|
930
|
+
method: 'GET',
|
|
931
|
+
url: '/',
|
|
932
|
+
constraints: { secret: 'alpha' },
|
|
933
|
+
handler: (req, reply) => {
|
|
934
|
+
reply.send({ hello: 'from alpha' })
|
|
935
|
+
}
|
|
936
|
+
})
|
|
937
|
+
|
|
938
|
+
fastify.route({
|
|
939
|
+
method: 'GET',
|
|
940
|
+
url: '/',
|
|
941
|
+
constraints: { secret: 'beta' },
|
|
942
|
+
handler: (req, reply) => {
|
|
943
|
+
reply.send({ hello: 'from beta' })
|
|
944
|
+
}
|
|
945
|
+
})
|
|
946
|
+
|
|
947
|
+
{
|
|
948
|
+
const res = await fastify.inject({
|
|
949
|
+
method: 'GET',
|
|
950
|
+
url: '/',
|
|
951
|
+
headers: {
|
|
952
|
+
'X-Secret': 'alpha'
|
|
953
|
+
}
|
|
954
|
+
})
|
|
955
|
+
t.assert.deepStrictEqual(JSON.parse(res.payload), { hello: 'from alpha' })
|
|
956
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
{
|
|
960
|
+
const res = await fastify.inject({
|
|
961
|
+
method: 'GET',
|
|
962
|
+
url: '/',
|
|
963
|
+
headers: {
|
|
964
|
+
'X-Secret': 'beta'
|
|
965
|
+
}
|
|
966
|
+
})
|
|
967
|
+
t.assert.deepStrictEqual(JSON.parse(res.payload), { hello: 'from beta' })
|
|
968
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
{
|
|
972
|
+
const res = await fastify.inject({
|
|
973
|
+
method: 'GET',
|
|
974
|
+
url: '/',
|
|
975
|
+
headers: {
|
|
976
|
+
'X-Secret': 'gamma'
|
|
977
|
+
}
|
|
978
|
+
})
|
|
979
|
+
t.assert.strictEqual(res.statusCode, 404)
|
|
980
|
+
}
|
|
981
|
+
})
|
|
982
|
+
|
|
983
|
+
test('Custom rotuerOptions constrained routes registered also for HEAD method generated by fastify', (t, done) => {
|
|
984
|
+
t.plan(3)
|
|
985
|
+
|
|
986
|
+
const constraint = {
|
|
987
|
+
name: 'secret',
|
|
988
|
+
storage: function () {
|
|
989
|
+
const secrets = {}
|
|
990
|
+
return {
|
|
991
|
+
get: (secret) => { return secrets[secret] || null },
|
|
992
|
+
set: (secret, store) => { secrets[secret] = store }
|
|
993
|
+
}
|
|
994
|
+
},
|
|
995
|
+
deriveConstraint: (req, ctx) => {
|
|
996
|
+
return req.headers['x-secret']
|
|
997
|
+
},
|
|
998
|
+
validate () { return true }
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
const fastify = Fastify({ routerOptions: { constraints: { secret: constraint } } })
|
|
1002
|
+
|
|
1003
|
+
fastify.route({
|
|
1004
|
+
method: 'GET',
|
|
1005
|
+
url: '/',
|
|
1006
|
+
constraints: { secret: 'mySecret' },
|
|
1007
|
+
handler: (req, reply) => {
|
|
1008
|
+
reply.send('from mySecret - my length is 31')
|
|
1009
|
+
}
|
|
1010
|
+
})
|
|
1011
|
+
|
|
1012
|
+
fastify.inject({
|
|
1013
|
+
method: 'HEAD',
|
|
1014
|
+
url: '/',
|
|
1015
|
+
headers: {
|
|
1016
|
+
'X-Secret': 'mySecret'
|
|
1017
|
+
}
|
|
1018
|
+
}, (err, res) => {
|
|
1019
|
+
t.assert.ifError(err)
|
|
1020
|
+
t.assert.deepStrictEqual(res.headers['content-length'], '31')
|
|
1021
|
+
t.assert.strictEqual(res.statusCode, 200)
|
|
1022
|
+
done()
|
|
1023
|
+
})
|
|
1024
|
+
})
|
|
1025
|
+
|
|
1026
|
+
test('allow async rotuerOptions constraints', async (t) => {
|
|
1027
|
+
t.plan(5)
|
|
1028
|
+
|
|
1029
|
+
const constraint = {
|
|
1030
|
+
name: 'secret',
|
|
1031
|
+
storage: function () {
|
|
1032
|
+
const secrets = {}
|
|
1033
|
+
return {
|
|
1034
|
+
get: (secret) => { return secrets[secret] || null },
|
|
1035
|
+
set: (secret, store) => { secrets[secret] = store }
|
|
1036
|
+
}
|
|
1037
|
+
},
|
|
1038
|
+
deriveConstraint: (req, ctx, done) => {
|
|
1039
|
+
done(null, req.headers['x-secret'])
|
|
1040
|
+
},
|
|
1041
|
+
validate () { return true }
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
const fastify = Fastify({ routerOptions: { constraints: { secret: constraint } } })
|
|
1045
|
+
|
|
1046
|
+
fastify.route({
|
|
1047
|
+
method: 'GET',
|
|
1048
|
+
url: '/',
|
|
1049
|
+
constraints: { secret: 'alpha' },
|
|
1050
|
+
handler: (req, reply) => {
|
|
1051
|
+
reply.send({ hello: 'from alpha' })
|
|
1052
|
+
}
|
|
1053
|
+
})
|
|
1054
|
+
|
|
1055
|
+
fastify.route({
|
|
1056
|
+
method: 'GET',
|
|
1057
|
+
url: '/',
|
|
1058
|
+
constraints: { secret: 'beta' },
|
|
1059
|
+
handler: (req, reply) => {
|
|
1060
|
+
reply.send({ hello: 'from beta' })
|
|
1061
|
+
}
|
|
1062
|
+
})
|
|
1063
|
+
|
|
1064
|
+
{
|
|
1065
|
+
const { statusCode, payload } = await fastify.inject({ method: 'GET', path: '/', headers: { 'X-Secret': 'alpha' } })
|
|
1066
|
+
t.assert.deepStrictEqual(JSON.parse(payload), { hello: 'from alpha' })
|
|
1067
|
+
t.assert.strictEqual(statusCode, 200)
|
|
1068
|
+
}
|
|
1069
|
+
{
|
|
1070
|
+
const { statusCode, payload } = await fastify.inject({ method: 'GET', path: '/', headers: { 'X-Secret': 'beta' } })
|
|
1071
|
+
t.assert.deepStrictEqual(JSON.parse(payload), { hello: 'from beta' })
|
|
1072
|
+
t.assert.strictEqual(statusCode, 200)
|
|
1073
|
+
}
|
|
1074
|
+
{
|
|
1075
|
+
const { statusCode } = await fastify.inject({ method: 'GET', path: '/', headers: { 'X-Secret': 'gamma' } })
|
|
1076
|
+
t.assert.strictEqual(statusCode, 404)
|
|
1077
|
+
}
|
|
1078
|
+
})
|
|
1079
|
+
|
|
1080
|
+
test('error in async rotuerOptions constraints', async (t) => {
|
|
1081
|
+
t.plan(8)
|
|
1082
|
+
|
|
1083
|
+
const constraint = {
|
|
1084
|
+
name: 'secret',
|
|
1085
|
+
storage: function () {
|
|
1086
|
+
const secrets = {}
|
|
1087
|
+
return {
|
|
1088
|
+
get: (secret) => { return secrets[secret] || null },
|
|
1089
|
+
set: (secret, store) => { secrets[secret] = store }
|
|
1090
|
+
}
|
|
1091
|
+
},
|
|
1092
|
+
deriveConstraint: (req, ctx, done) => {
|
|
1093
|
+
done(Error('kaboom'))
|
|
1094
|
+
},
|
|
1095
|
+
validate () { return true }
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
const fastify = Fastify({ routerOptions: { constraints: { secret: constraint } } })
|
|
1099
|
+
|
|
1100
|
+
fastify.route({
|
|
1101
|
+
method: 'GET',
|
|
1102
|
+
url: '/',
|
|
1103
|
+
constraints: { secret: 'alpha' },
|
|
1104
|
+
handler: (req, reply) => {
|
|
1105
|
+
reply.send({ hello: 'from alpha' })
|
|
1106
|
+
}
|
|
1107
|
+
})
|
|
1108
|
+
|
|
1109
|
+
fastify.route({
|
|
1110
|
+
method: 'GET',
|
|
1111
|
+
url: '/',
|
|
1112
|
+
constraints: { secret: 'beta' },
|
|
1113
|
+
handler: (req, reply) => {
|
|
1114
|
+
reply.send({ hello: 'from beta' })
|
|
1115
|
+
}
|
|
1116
|
+
})
|
|
1117
|
+
|
|
1118
|
+
{
|
|
1119
|
+
const { statusCode, payload } = await fastify.inject({ method: 'GET', path: '/', headers: { 'X-Secret': 'alpha' } })
|
|
1120
|
+
t.assert.deepStrictEqual(JSON.parse(payload), { error: 'Internal Server Error', message: 'Unexpected error from async constraint', statusCode: 500 })
|
|
1121
|
+
t.assert.strictEqual(statusCode, 500)
|
|
1122
|
+
}
|
|
1123
|
+
{
|
|
1124
|
+
const { statusCode, payload } = await fastify.inject({ method: 'GET', path: '/', headers: { 'X-Secret': 'beta' } })
|
|
1125
|
+
t.assert.deepStrictEqual(JSON.parse(payload), { error: 'Internal Server Error', message: 'Unexpected error from async constraint', statusCode: 500 })
|
|
1126
|
+
t.assert.strictEqual(statusCode, 500)
|
|
1127
|
+
}
|
|
1128
|
+
{
|
|
1129
|
+
const { statusCode, payload } = await fastify.inject({ method: 'GET', path: '/', headers: { 'X-Secret': 'gamma' } })
|
|
1130
|
+
t.assert.deepStrictEqual(JSON.parse(payload), { error: 'Internal Server Error', message: 'Unexpected error from async constraint', statusCode: 500 })
|
|
1131
|
+
t.assert.strictEqual(statusCode, 500)
|
|
1132
|
+
}
|
|
1133
|
+
{
|
|
1134
|
+
const { statusCode, payload } = await fastify.inject({ method: 'GET', path: '/' })
|
|
1135
|
+
t.assert.deepStrictEqual(JSON.parse(payload), { error: 'Internal Server Error', message: 'Unexpected error from async constraint', statusCode: 500 })
|
|
1136
|
+
t.assert.strictEqual(statusCode, 500)
|
|
1137
|
+
}
|
|
1138
|
+
})
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
const { test } = require('node:test')
|
|
4
4
|
const http = require('node:http')
|
|
5
5
|
const dns = require('node:dns').promises
|
|
6
|
-
const sget = require('simple-get').concat
|
|
7
6
|
const Fastify = require('..')
|
|
8
7
|
const { FST_ERR_FORCE_CLOSE_CONNECTIONS_IDLE_NOT_AVAILABLE } = require('../lib/errors')
|
|
9
8
|
|
|
@@ -11,7 +10,7 @@ async function setup () {
|
|
|
11
10
|
const localAddresses = await dns.lookup('localhost', { all: true })
|
|
12
11
|
|
|
13
12
|
test('Should support a custom http server', { skip: localAddresses.length < 1 }, async t => {
|
|
14
|
-
t.plan(
|
|
13
|
+
t.plan(5)
|
|
15
14
|
|
|
16
15
|
const fastify = Fastify({
|
|
17
16
|
serverFactory: (handler, opts) => {
|
|
@@ -34,20 +33,13 @@ async function setup () {
|
|
|
34
33
|
|
|
35
34
|
await fastify.listen({ port: 0 })
|
|
36
35
|
|
|
37
|
-
await
|
|
38
|
-
|
|
39
|
-
method: 'GET',
|
|
40
|
-
url: 'http://localhost:' + fastify.server.address().port,
|
|
41
|
-
rejectUnauthorized: false
|
|
42
|
-
}, (err, response, body) => {
|
|
43
|
-
if (err) {
|
|
44
|
-
return reject(err)
|
|
45
|
-
}
|
|
46
|
-
t.assert.strictEqual(response.statusCode, 200)
|
|
47
|
-
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
|
48
|
-
resolve()
|
|
49
|
-
})
|
|
36
|
+
const response = await fetch('http://localhost:' + fastify.server.address().port, {
|
|
37
|
+
method: 'GET'
|
|
50
38
|
})
|
|
39
|
+
t.assert.ok(response.ok)
|
|
40
|
+
t.assert.strictEqual(response.status, 200)
|
|
41
|
+
const body = await response.text()
|
|
42
|
+
t.assert.deepStrictEqual(JSON.parse(body), { hello: 'world' })
|
|
51
43
|
})
|
|
52
44
|
|
|
53
45
|
test('Should not allow forceCloseConnection=idle if the server does not support closeIdleConnections', t => {
|