fastify 4.19.2 → 4.21.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/.c8rc.json +8 -0
- package/.taprc +3 -2
- package/README.md +2 -1
- package/SECURITY.md +9 -0
- package/docs/Guides/Prototype-Poisoning.md +2 -2
- package/docs/Reference/Errors.md +39 -17
- package/docs/Reference/Logging.md +1 -1
- package/docs/Reference/Plugins.md +4 -0
- package/docs/Reference/Routes.md +8 -0
- package/docs/Reference/Server.md +230 -178
- package/docs/Reference/TypeScript.md +1 -1
- package/fastify.d.ts +3 -2
- package/fastify.js +36 -17
- package/lib/context.js +6 -0
- package/lib/errors.js +51 -20
- package/lib/fourOhFour.js +5 -9
- package/lib/handleRequest.js +3 -5
- package/lib/hooks.js +91 -25
- package/lib/logger.js +40 -3
- package/lib/reply.js +19 -13
- package/lib/reqIdGenFactory.js +18 -3
- package/lib/route.js +14 -61
- package/lib/schema-controller.js +2 -0
- package/lib/server.js +23 -8
- package/lib/symbols.js +1 -0
- package/package.json +8 -10
- package/test/500s.test.js +22 -0
- package/test/async-await.test.js +1 -1
- package/test/childLoggerFactory.test.js +91 -0
- package/test/encapsulated-child-logger-factory.test.js +69 -0
- package/test/fastify-instance.test.js +43 -10
- package/test/inject.test.js +1 -2
- package/test/internals/errors.test.js +843 -0
- package/test/internals/hookRunner.test.js +22 -8
- package/test/internals/initialConfig.test.js +9 -2
- package/test/internals/reply.test.js +82 -45
- package/test/internals/reqIdGenFactory.test.js +129 -0
- package/test/internals/request-validate.test.js +40 -1
- package/test/internals/request.test.js +14 -4
- package/test/reply-error.test.js +25 -0
- package/test/request-id.test.js +131 -0
- package/test/route.test.js +135 -0
- package/test/serial/logger.0.test.js +6 -1
- package/test/server.test.js +64 -2
- package/test/stream.test.js +4 -4
- package/test/types/errors.test-d.ts +82 -0
- package/test/types/fastify.test-d.ts +4 -0
- package/test/types/instance.test-d.ts +37 -0
- package/test/types/reply.test-d.ts +26 -0
- package/test/types/route.test-d.ts +3 -0
- package/test/types/type-provider.test-d.ts +56 -0
- package/types/errors.d.ts +29 -23
- package/types/instance.d.ts +33 -7
- package/types/logger.d.ts +25 -0
- package/types/reply.d.ts +8 -6
- package/types/route.d.ts +2 -1
- package/types/type-provider.d.ts +2 -1
- package/types/utils.d.ts +9 -0
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
const t = require('tap')
|
|
4
4
|
const test = t.test
|
|
5
|
-
const {
|
|
5
|
+
const { hookRunnerGenerator, onSendHookRunner } = require('../../lib/hooks')
|
|
6
6
|
|
|
7
7
|
test('hookRunner - Basic', t => {
|
|
8
8
|
t.plan(9)
|
|
9
9
|
|
|
10
|
-
hookRunner
|
|
10
|
+
const hookRunner = hookRunnerGenerator(iterator)
|
|
11
|
+
|
|
12
|
+
hookRunner([fn1, fn2, fn3], 'a', 'b', done)
|
|
11
13
|
|
|
12
14
|
function iterator (fn, a, b, done) {
|
|
13
15
|
return fn(a, b, done)
|
|
@@ -41,7 +43,9 @@ test('hookRunner - Basic', t => {
|
|
|
41
43
|
test('hookRunner - In case of error should skip to done', t => {
|
|
42
44
|
t.plan(7)
|
|
43
45
|
|
|
44
|
-
hookRunner
|
|
46
|
+
const hookRunner = hookRunnerGenerator(iterator)
|
|
47
|
+
|
|
48
|
+
hookRunner([fn1, fn2, fn3], 'a', 'b', done)
|
|
45
49
|
|
|
46
50
|
function iterator (fn, a, b, done) {
|
|
47
51
|
return fn(a, b, done)
|
|
@@ -73,7 +77,9 @@ test('hookRunner - In case of error should skip to done', t => {
|
|
|
73
77
|
test('hookRunner - Should handle throw', t => {
|
|
74
78
|
t.plan(7)
|
|
75
79
|
|
|
76
|
-
hookRunner
|
|
80
|
+
const hookRunner = hookRunnerGenerator(iterator)
|
|
81
|
+
|
|
82
|
+
hookRunner([fn1, fn2, fn3], 'a', 'b', done)
|
|
77
83
|
|
|
78
84
|
function iterator (fn, a, b, done) {
|
|
79
85
|
return fn(a, b, done)
|
|
@@ -105,7 +111,9 @@ test('hookRunner - Should handle throw', t => {
|
|
|
105
111
|
test('hookRunner - Should handle promises', t => {
|
|
106
112
|
t.plan(9)
|
|
107
113
|
|
|
108
|
-
hookRunner
|
|
114
|
+
const hookRunner = hookRunnerGenerator(iterator)
|
|
115
|
+
|
|
116
|
+
hookRunner([fn1, fn2, fn3], 'a', 'b', done)
|
|
109
117
|
|
|
110
118
|
function iterator (fn, a, b, done) {
|
|
111
119
|
return fn(a, b, done)
|
|
@@ -139,7 +147,9 @@ test('hookRunner - Should handle promises', t => {
|
|
|
139
147
|
test('hookRunner - In case of error should skip to done (with promises)', t => {
|
|
140
148
|
t.plan(7)
|
|
141
149
|
|
|
142
|
-
hookRunner
|
|
150
|
+
const hookRunner = hookRunnerGenerator(iterator)
|
|
151
|
+
|
|
152
|
+
hookRunner([fn1, fn2, fn3], 'a', 'b', done)
|
|
143
153
|
|
|
144
154
|
function iterator (fn, a, b, done) {
|
|
145
155
|
return fn(a, b, done)
|
|
@@ -171,8 +181,10 @@ test('hookRunner - In case of error should skip to done (with promises)', t => {
|
|
|
171
181
|
test('hookRunner - Be able to exit before its natural end', t => {
|
|
172
182
|
t.plan(4)
|
|
173
183
|
|
|
184
|
+
const hookRunner = hookRunnerGenerator(iterator)
|
|
185
|
+
|
|
174
186
|
let shouldStop = false
|
|
175
|
-
hookRunner([fn1, fn2, fn3],
|
|
187
|
+
hookRunner([fn1, fn2, fn3], 'a', 'b', done)
|
|
176
188
|
|
|
177
189
|
function iterator (fn, a, b, done) {
|
|
178
190
|
if (shouldStop) {
|
|
@@ -208,7 +220,9 @@ test('hookRunner - Promises that resolve to a value do not change the state', t
|
|
|
208
220
|
|
|
209
221
|
const originalState = { a: 'a', b: 'b' }
|
|
210
222
|
|
|
211
|
-
hookRunner
|
|
223
|
+
const hookRunner = hookRunnerGenerator(iterator)
|
|
224
|
+
|
|
225
|
+
hookRunner([fn1, fn2, fn3], originalState, 'b', done)
|
|
212
226
|
|
|
213
227
|
function iterator (fn, state, b, done) {
|
|
214
228
|
return fn(state, b, done)
|
|
@@ -55,7 +55,7 @@ test('without options passed to Fastify, initialConfig should expose default val
|
|
|
55
55
|
})
|
|
56
56
|
|
|
57
57
|
test('Fastify.initialConfig should expose all options', t => {
|
|
58
|
-
t.plan(
|
|
58
|
+
t.plan(21)
|
|
59
59
|
|
|
60
60
|
const serverFactory = (handler, opts) => {
|
|
61
61
|
const server = http.createServer((req, res) => {
|
|
@@ -132,6 +132,7 @@ test('Fastify.initialConfig should expose all options', t => {
|
|
|
132
132
|
t.equal(fastify.initialConfig.serverFactory, undefined)
|
|
133
133
|
t.equal(fastify.initialConfig.trustProxy, undefined)
|
|
134
134
|
t.equal(fastify.initialConfig.genReqId, undefined)
|
|
135
|
+
t.equal(fastify.initialConfig.childLoggerFactory, undefined)
|
|
135
136
|
t.equal(fastify.initialConfig.querystringParser, undefined)
|
|
136
137
|
t.equal(fastify.initialConfig.logger, undefined)
|
|
137
138
|
t.equal(fastify.initialConfig.trustProxy, undefined)
|
|
@@ -243,7 +244,7 @@ test('Original options must not be altered (test deep cloning)', t => {
|
|
|
243
244
|
})
|
|
244
245
|
|
|
245
246
|
test('Should not have issues when passing stream options to Pino.js', t => {
|
|
246
|
-
t.plan(
|
|
247
|
+
t.plan(17)
|
|
247
248
|
|
|
248
249
|
const stream = split(JSON.parse)
|
|
249
250
|
|
|
@@ -259,6 +260,10 @@ test('Should not have issues when passing stream options to Pino.js', t => {
|
|
|
259
260
|
|
|
260
261
|
try {
|
|
261
262
|
fastify = Fastify(originalOptions)
|
|
263
|
+
fastify.setChildLoggerFactory(function (logger, bindings, opts) {
|
|
264
|
+
bindings.someBinding = 'value'
|
|
265
|
+
return logger.child(bindings, opts)
|
|
266
|
+
})
|
|
262
267
|
|
|
263
268
|
t.type(fastify, 'object')
|
|
264
269
|
t.same(fastify.initialConfig, {
|
|
@@ -297,6 +302,7 @@ test('Should not have issues when passing stream options to Pino.js', t => {
|
|
|
297
302
|
stream.once('data', line => {
|
|
298
303
|
const id = line.reqId
|
|
299
304
|
t.ok(line.reqId, 'reqId is defined')
|
|
305
|
+
t.equal(line.someBinding, 'value', 'child logger binding is set')
|
|
300
306
|
t.ok(line.req, 'req is defined')
|
|
301
307
|
t.equal(line.msg, 'incoming request', 'message is set')
|
|
302
308
|
t.equal(line.req.method, 'GET', 'method is get')
|
|
@@ -304,6 +310,7 @@ test('Should not have issues when passing stream options to Pino.js', t => {
|
|
|
304
310
|
stream.once('data', line => {
|
|
305
311
|
t.equal(line.reqId, id)
|
|
306
312
|
t.ok(line.reqId, 'reqId is defined')
|
|
313
|
+
t.equal(line.someBinding, 'value', 'child logger binding is set')
|
|
307
314
|
t.ok(line.res, 'res is defined')
|
|
308
315
|
t.equal(line.msg, 'request completed', 'message is set')
|
|
309
316
|
t.equal(line.res.statusCode, 200, 'statusCode is 200')
|
|
@@ -6,6 +6,7 @@ const sget = require('simple-get').concat
|
|
|
6
6
|
const http = require('http')
|
|
7
7
|
const NotFound = require('http-errors').NotFound
|
|
8
8
|
const Reply = require('../../lib/reply')
|
|
9
|
+
const Fastify = require('../..')
|
|
9
10
|
const { Readable, Writable } = require('stream')
|
|
10
11
|
const {
|
|
11
12
|
kReplyErrorHandlerCalled,
|
|
@@ -19,9 +20,11 @@ const fs = require('fs')
|
|
|
19
20
|
const path = require('path')
|
|
20
21
|
const warning = require('../../lib/warnings')
|
|
21
22
|
|
|
23
|
+
const agent = new http.Agent({ keepAlive: false })
|
|
24
|
+
|
|
22
25
|
const doGet = function (url) {
|
|
23
26
|
return new Promise((resolve, reject) => {
|
|
24
|
-
sget({ method: 'GET', url, followRedirects: false }, (err, response, body) => {
|
|
27
|
+
sget({ method: 'GET', url, followRedirects: false, agent }, (err, response, body) => {
|
|
25
28
|
if (err) {
|
|
26
29
|
reject(err)
|
|
27
30
|
} else {
|
|
@@ -128,7 +131,8 @@ test('reply.serializer should set a custom serializer', t => {
|
|
|
128
131
|
|
|
129
132
|
test('reply.serializer should support running preSerialization hooks', t => {
|
|
130
133
|
t.plan(3)
|
|
131
|
-
const fastify =
|
|
134
|
+
const fastify = Fastify()
|
|
135
|
+
t.teardown(fastify.close.bind(fastify))
|
|
132
136
|
|
|
133
137
|
fastify.addHook('preSerialization', async (request, reply, payload) => { t.ok('called', 'preSerialization') })
|
|
134
138
|
fastify.route({
|
|
@@ -182,7 +186,8 @@ test('reply.serialize should serialize payload with a context default serializer
|
|
|
182
186
|
|
|
183
187
|
test('reply.serialize should serialize payload with Fastify instance', t => {
|
|
184
188
|
t.plan(2)
|
|
185
|
-
const fastify =
|
|
189
|
+
const fastify = Fastify()
|
|
190
|
+
t.teardown(fastify.close.bind(fastify))
|
|
186
191
|
fastify.route({
|
|
187
192
|
method: 'GET',
|
|
188
193
|
url: '/',
|
|
@@ -213,7 +218,8 @@ test('reply.serialize should serialize payload with Fastify instance', t => {
|
|
|
213
218
|
})
|
|
214
219
|
|
|
215
220
|
test('within an instance', t => {
|
|
216
|
-
const fastify =
|
|
221
|
+
const fastify = Fastify()
|
|
222
|
+
t.teardown(fastify.close.bind(fastify))
|
|
217
223
|
const test = t.test
|
|
218
224
|
|
|
219
225
|
fastify.get('/', function (req, reply) {
|
|
@@ -434,7 +440,7 @@ test('within an instance', t => {
|
|
|
434
440
|
test('buffer without content type should send a application/octet-stream and raw buffer', t => {
|
|
435
441
|
t.plan(4)
|
|
436
442
|
|
|
437
|
-
const fastify =
|
|
443
|
+
const fastify = Fastify()
|
|
438
444
|
|
|
439
445
|
fastify.get('/', function (req, reply) {
|
|
440
446
|
reply.send(Buffer.alloc(1024))
|
|
@@ -457,7 +463,7 @@ test('buffer without content type should send a application/octet-stream and raw
|
|
|
457
463
|
test('Uint8Array without content type should send a application/octet-stream and raw buffer', t => {
|
|
458
464
|
t.plan(4)
|
|
459
465
|
|
|
460
|
-
const fastify =
|
|
466
|
+
const fastify = Fastify()
|
|
461
467
|
|
|
462
468
|
fastify.get('/', function (req, reply) {
|
|
463
469
|
reply.send(new Uint8Array(1024).fill(0xff))
|
|
@@ -480,7 +486,7 @@ test('Uint8Array without content type should send a application/octet-stream and
|
|
|
480
486
|
test('Uint16Array without content type should send a application/octet-stream and raw buffer', t => {
|
|
481
487
|
t.plan(4)
|
|
482
488
|
|
|
483
|
-
const fastify =
|
|
489
|
+
const fastify = Fastify()
|
|
484
490
|
|
|
485
491
|
fastify.get('/', function (req, reply) {
|
|
486
492
|
reply.send(new Uint16Array(50).fill(0xffffffff))
|
|
@@ -503,7 +509,7 @@ test('Uint16Array without content type should send a application/octet-stream an
|
|
|
503
509
|
test('TypedArray with content type should not send application/octet-stream', t => {
|
|
504
510
|
t.plan(4)
|
|
505
511
|
|
|
506
|
-
const fastify =
|
|
512
|
+
const fastify = Fastify()
|
|
507
513
|
|
|
508
514
|
fastify.get('/', function (req, reply) {
|
|
509
515
|
reply.header('Content-Type', 'text/plain')
|
|
@@ -527,7 +533,7 @@ test('TypedArray with content type should not send application/octet-stream', t
|
|
|
527
533
|
test('buffer with content type should not send application/octet-stream', t => {
|
|
528
534
|
t.plan(4)
|
|
529
535
|
|
|
530
|
-
const fastify =
|
|
536
|
+
const fastify = Fastify()
|
|
531
537
|
|
|
532
538
|
fastify.get('/', function (req, reply) {
|
|
533
539
|
reply.header('Content-Type', 'text/plain')
|
|
@@ -552,7 +558,7 @@ test('buffer with content type should not send application/octet-stream', t => {
|
|
|
552
558
|
test('stream with content type should not send application/octet-stream', t => {
|
|
553
559
|
t.plan(4)
|
|
554
560
|
|
|
555
|
-
const fastify =
|
|
561
|
+
const fastify = Fastify()
|
|
556
562
|
|
|
557
563
|
const streamPath = path.join(__dirname, '..', '..', 'package.json')
|
|
558
564
|
const stream = fs.createReadStream(streamPath)
|
|
@@ -579,7 +585,7 @@ test('stream with content type should not send application/octet-stream', t => {
|
|
|
579
585
|
test('stream without content type should not send application/octet-stream', t => {
|
|
580
586
|
t.plan(4)
|
|
581
587
|
|
|
582
|
-
const fastify =
|
|
588
|
+
const fastify = Fastify()
|
|
583
589
|
|
|
584
590
|
const stream = fs.createReadStream(__filename)
|
|
585
591
|
const buf = fs.readFileSync(__filename)
|
|
@@ -605,7 +611,7 @@ test('stream without content type should not send application/octet-stream', t =
|
|
|
605
611
|
test('stream using reply.raw.writeHead should return customize headers', t => {
|
|
606
612
|
t.plan(6)
|
|
607
613
|
|
|
608
|
-
const fastify =
|
|
614
|
+
const fastify = Fastify()
|
|
609
615
|
const fs = require('fs')
|
|
610
616
|
const path = require('path')
|
|
611
617
|
|
|
@@ -641,7 +647,7 @@ test('stream using reply.raw.writeHead should return customize headers', t => {
|
|
|
641
647
|
test('plain string without content type should send a text/plain', t => {
|
|
642
648
|
t.plan(4)
|
|
643
649
|
|
|
644
|
-
const fastify =
|
|
650
|
+
const fastify = Fastify()
|
|
645
651
|
|
|
646
652
|
fastify.get('/', function (req, reply) {
|
|
647
653
|
reply.send('hello world!')
|
|
@@ -665,7 +671,7 @@ test('plain string without content type should send a text/plain', t => {
|
|
|
665
671
|
test('plain string with content type should be sent unmodified', t => {
|
|
666
672
|
t.plan(4)
|
|
667
673
|
|
|
668
|
-
const fastify =
|
|
674
|
+
const fastify = Fastify()
|
|
669
675
|
|
|
670
676
|
fastify.get('/', function (req, reply) {
|
|
671
677
|
reply.type('text/css').send('hello world!')
|
|
@@ -689,7 +695,7 @@ test('plain string with content type should be sent unmodified', t => {
|
|
|
689
695
|
test('plain string with content type and custom serializer should be serialized', t => {
|
|
690
696
|
t.plan(4)
|
|
691
697
|
|
|
692
|
-
const fastify =
|
|
698
|
+
const fastify = Fastify()
|
|
693
699
|
|
|
694
700
|
fastify.get('/', function (req, reply) {
|
|
695
701
|
reply
|
|
@@ -716,7 +722,7 @@ test('plain string with content type and custom serializer should be serialized'
|
|
|
716
722
|
test('plain string with content type application/json should NOT be serialized as json', t => {
|
|
717
723
|
t.plan(4)
|
|
718
724
|
|
|
719
|
-
const fastify =
|
|
725
|
+
const fastify = Fastify()
|
|
720
726
|
|
|
721
727
|
fastify.get('/', function (req, reply) {
|
|
722
728
|
reply.type('application/json').send('{"key": "hello world!"}')
|
|
@@ -740,7 +746,7 @@ test('plain string with content type application/json should NOT be serialized a
|
|
|
740
746
|
test('plain string with custom json content type should NOT be serialized as json', t => {
|
|
741
747
|
t.plan(19)
|
|
742
748
|
|
|
743
|
-
const fastify =
|
|
749
|
+
const fastify = Fastify()
|
|
744
750
|
|
|
745
751
|
const customSamples = {
|
|
746
752
|
collectionjson: {
|
|
@@ -795,7 +801,7 @@ test('plain string with custom json content type should NOT be serialized as jso
|
|
|
795
801
|
test('non-string with content type application/json SHOULD be serialized as json', t => {
|
|
796
802
|
t.plan(4)
|
|
797
803
|
|
|
798
|
-
const fastify =
|
|
804
|
+
const fastify = Fastify()
|
|
799
805
|
|
|
800
806
|
fastify.get('/', function (req, reply) {
|
|
801
807
|
reply.type('application/json').send({ key: 'hello world!' })
|
|
@@ -819,7 +825,7 @@ test('non-string with content type application/json SHOULD be serialized as json
|
|
|
819
825
|
test('non-string with custom json\'s content-type SHOULD be serialized as json', t => {
|
|
820
826
|
t.plan(4)
|
|
821
827
|
|
|
822
|
-
const fastify =
|
|
828
|
+
const fastify = Fastify()
|
|
823
829
|
|
|
824
830
|
fastify.get('/', function (req, reply) {
|
|
825
831
|
reply.type('application/json; version=2; ').send({ key: 'hello world!' })
|
|
@@ -843,7 +849,7 @@ test('non-string with custom json\'s content-type SHOULD be serialized as json',
|
|
|
843
849
|
test('non-string with custom json content type SHOULD be serialized as json', t => {
|
|
844
850
|
t.plan(16)
|
|
845
851
|
|
|
846
|
-
const fastify =
|
|
852
|
+
const fastify = Fastify()
|
|
847
853
|
|
|
848
854
|
const customSamples = {
|
|
849
855
|
collectionjson: {
|
|
@@ -894,7 +900,7 @@ test('non-string with custom json content type SHOULD be serialized as json', t
|
|
|
894
900
|
test('error object with a content type that is not application/json should work', t => {
|
|
895
901
|
t.plan(6)
|
|
896
902
|
|
|
897
|
-
const fastify =
|
|
903
|
+
const fastify = Fastify()
|
|
898
904
|
|
|
899
905
|
fastify.get('/text', function (req, reply) {
|
|
900
906
|
reply.type('text/plain')
|
|
@@ -928,7 +934,7 @@ test('error object with a content type that is not application/json should work'
|
|
|
928
934
|
test('undefined payload should be sent as-is', t => {
|
|
929
935
|
t.plan(6)
|
|
930
936
|
|
|
931
|
-
const fastify =
|
|
937
|
+
const fastify = Fastify()
|
|
932
938
|
|
|
933
939
|
fastify.addHook('onSend', function (request, reply, payload, done) {
|
|
934
940
|
t.equal(payload, undefined)
|
|
@@ -958,7 +964,7 @@ test('undefined payload should be sent as-is', t => {
|
|
|
958
964
|
test('for HEAD method, no body should be sent but content-length should be', t => {
|
|
959
965
|
t.plan(11)
|
|
960
966
|
|
|
961
|
-
const fastify =
|
|
967
|
+
const fastify = Fastify()
|
|
962
968
|
const contentType = 'application/json; charset=utf-8'
|
|
963
969
|
const bodySize = JSON.stringify({ foo: 'bar' }).length
|
|
964
970
|
|
|
@@ -1013,7 +1019,7 @@ test('for HEAD method, no body should be sent but content-length should be', t =
|
|
|
1013
1019
|
test('reply.send(new NotFound()) should not invoke the 404 handler', t => {
|
|
1014
1020
|
t.plan(9)
|
|
1015
1021
|
|
|
1016
|
-
const fastify =
|
|
1022
|
+
const fastify = Fastify()
|
|
1017
1023
|
|
|
1018
1024
|
fastify.setNotFoundHandler((req, reply) => {
|
|
1019
1025
|
t.fail('Should not be called')
|
|
@@ -1389,7 +1395,7 @@ test('Content type and charset set previously', t => {
|
|
|
1389
1395
|
|
|
1390
1396
|
test('.status() is an alias for .code()', t => {
|
|
1391
1397
|
t.plan(2)
|
|
1392
|
-
const fastify =
|
|
1398
|
+
const fastify = Fastify()
|
|
1393
1399
|
|
|
1394
1400
|
fastify.get('/', function (req, reply) {
|
|
1395
1401
|
reply.status(418).send()
|
|
@@ -1403,7 +1409,7 @@ test('.status() is an alias for .code()', t => {
|
|
|
1403
1409
|
|
|
1404
1410
|
test('.statusCode is getter and setter', t => {
|
|
1405
1411
|
t.plan(4)
|
|
1406
|
-
const fastify =
|
|
1412
|
+
const fastify = Fastify()
|
|
1407
1413
|
|
|
1408
1414
|
fastify.get('/', function (req, reply) {
|
|
1409
1415
|
t.ok(reply.statusCode, 200, 'default status value')
|
|
@@ -1455,7 +1461,7 @@ test('reply.header setting multiple cookies as multiple Set-Cookie headers', t =
|
|
|
1455
1461
|
|
|
1456
1462
|
test('should emit deprecation warning when trying to modify the reply.sent property', t => {
|
|
1457
1463
|
t.plan(4)
|
|
1458
|
-
const fastify =
|
|
1464
|
+
const fastify = Fastify()
|
|
1459
1465
|
|
|
1460
1466
|
const deprecationCode = 'FSTDEP010'
|
|
1461
1467
|
warning.emitted.delete(deprecationCode)
|
|
@@ -1483,7 +1489,7 @@ test('should emit deprecation warning when trying to modify the reply.sent prope
|
|
|
1483
1489
|
|
|
1484
1490
|
test('should throw error when passing falsy value to reply.sent', t => {
|
|
1485
1491
|
t.plan(4)
|
|
1486
|
-
const fastify =
|
|
1492
|
+
const fastify = Fastify()
|
|
1487
1493
|
|
|
1488
1494
|
fastify.get('/', function (req, reply) {
|
|
1489
1495
|
try {
|
|
@@ -1502,8 +1508,8 @@ test('should throw error when passing falsy value to reply.sent', t => {
|
|
|
1502
1508
|
})
|
|
1503
1509
|
|
|
1504
1510
|
test('should throw error when attempting to set reply.sent more than once', t => {
|
|
1505
|
-
t.plan(
|
|
1506
|
-
const fastify =
|
|
1511
|
+
t.plan(3)
|
|
1512
|
+
const fastify = Fastify()
|
|
1507
1513
|
|
|
1508
1514
|
fastify.get('/', function (req, reply) {
|
|
1509
1515
|
reply.sent = true
|
|
@@ -1512,7 +1518,6 @@ test('should throw error when attempting to set reply.sent more than once', t =>
|
|
|
1512
1518
|
t.fail('must throw')
|
|
1513
1519
|
} catch (err) {
|
|
1514
1520
|
t.equal(err.code, 'FST_ERR_REP_ALREADY_SENT')
|
|
1515
|
-
t.equal(err.message, 'Reply was already sent.')
|
|
1516
1521
|
}
|
|
1517
1522
|
reply.raw.end()
|
|
1518
1523
|
})
|
|
@@ -1525,7 +1530,7 @@ test('should throw error when attempting to set reply.sent more than once', t =>
|
|
|
1525
1530
|
|
|
1526
1531
|
test('should not throw error when attempting to set reply.sent if the underlining request was sent', t => {
|
|
1527
1532
|
t.plan(3)
|
|
1528
|
-
const fastify =
|
|
1533
|
+
const fastify = Fastify()
|
|
1529
1534
|
|
|
1530
1535
|
fastify.get('/', function (req, reply) {
|
|
1531
1536
|
reply.raw.end()
|
|
@@ -1549,7 +1554,7 @@ test('reply.getResponseTime() should return 0 before the timer is initialised on
|
|
|
1549
1554
|
|
|
1550
1555
|
test('reply.getResponseTime() should return a number greater than 0 after the timer is initialised on the reply by setting up response listeners', t => {
|
|
1551
1556
|
t.plan(1)
|
|
1552
|
-
const fastify =
|
|
1557
|
+
const fastify = Fastify()
|
|
1553
1558
|
fastify.route({
|
|
1554
1559
|
method: 'GET',
|
|
1555
1560
|
url: '/',
|
|
@@ -1568,7 +1573,7 @@ test('reply.getResponseTime() should return a number greater than 0 after the ti
|
|
|
1568
1573
|
|
|
1569
1574
|
test('reply.getResponseTime() should return the time since a request started while inflight', t => {
|
|
1570
1575
|
t.plan(1)
|
|
1571
|
-
const fastify =
|
|
1576
|
+
const fastify = Fastify()
|
|
1572
1577
|
fastify.route({
|
|
1573
1578
|
method: 'GET',
|
|
1574
1579
|
url: '/',
|
|
@@ -1591,7 +1596,7 @@ test('reply.getResponseTime() should return the time since a request started whi
|
|
|
1591
1596
|
|
|
1592
1597
|
test('reply.getResponseTime() should return the same value after a request is finished', t => {
|
|
1593
1598
|
t.plan(1)
|
|
1594
|
-
const fastify =
|
|
1599
|
+
const fastify = Fastify()
|
|
1595
1600
|
fastify.route({
|
|
1596
1601
|
method: 'GET',
|
|
1597
1602
|
url: '/',
|
|
@@ -1610,7 +1615,7 @@ test('reply.getResponseTime() should return the same value after a request is fi
|
|
|
1610
1615
|
|
|
1611
1616
|
test('reply should use the custom serializer', t => {
|
|
1612
1617
|
t.plan(4)
|
|
1613
|
-
const fastify =
|
|
1618
|
+
const fastify = Fastify()
|
|
1614
1619
|
fastify.setReplySerializer((payload, statusCode) => {
|
|
1615
1620
|
t.same(payload, { foo: 'bar' })
|
|
1616
1621
|
t.equal(statusCode, 200)
|
|
@@ -1638,7 +1643,7 @@ test('reply should use the custom serializer', t => {
|
|
|
1638
1643
|
test('reply should use the right serializer in encapsulated context', t => {
|
|
1639
1644
|
t.plan(9)
|
|
1640
1645
|
|
|
1641
|
-
const fastify =
|
|
1646
|
+
const fastify = Fastify()
|
|
1642
1647
|
fastify.setReplySerializer((payload) => {
|
|
1643
1648
|
t.same(payload, { foo: 'bar' })
|
|
1644
1649
|
payload.foo = 'bar bar'
|
|
@@ -1707,7 +1712,7 @@ test('reply should use the right serializer in encapsulated context', t => {
|
|
|
1707
1712
|
test('reply should use the right serializer in deep encapsulated context', t => {
|
|
1708
1713
|
t.plan(8)
|
|
1709
1714
|
|
|
1710
|
-
const fastify =
|
|
1715
|
+
const fastify = Fastify()
|
|
1711
1716
|
|
|
1712
1717
|
fastify.route({
|
|
1713
1718
|
method: 'GET',
|
|
@@ -1771,7 +1776,7 @@ test('reply should use the right serializer in deep encapsulated context', t =>
|
|
|
1771
1776
|
test('reply should use the route serializer', t => {
|
|
1772
1777
|
t.plan(3)
|
|
1773
1778
|
|
|
1774
|
-
const fastify =
|
|
1779
|
+
const fastify = Fastify()
|
|
1775
1780
|
fastify.setReplySerializer(() => {
|
|
1776
1781
|
t.fail('this serializer should not be executed')
|
|
1777
1782
|
})
|
|
@@ -1802,7 +1807,7 @@ test('reply should use the route serializer', t => {
|
|
|
1802
1807
|
test('cannot set the replySerializer when the server is running', t => {
|
|
1803
1808
|
t.plan(2)
|
|
1804
1809
|
|
|
1805
|
-
const fastify =
|
|
1810
|
+
const fastify = Fastify()
|
|
1806
1811
|
t.teardown(fastify.close.bind(fastify))
|
|
1807
1812
|
|
|
1808
1813
|
fastify.listen({ port: 0 }, err => {
|
|
@@ -1819,7 +1824,7 @@ test('cannot set the replySerializer when the server is running', t => {
|
|
|
1819
1824
|
test('reply should not call the custom serializer for errors and not found', t => {
|
|
1820
1825
|
t.plan(9)
|
|
1821
1826
|
|
|
1822
|
-
const fastify =
|
|
1827
|
+
const fastify = Fastify()
|
|
1823
1828
|
fastify.setReplySerializer((payload, statusCode) => {
|
|
1824
1829
|
t.same(payload, { foo: 'bar' })
|
|
1825
1830
|
t.equal(statusCode, 200)
|
|
@@ -1935,7 +1940,7 @@ test('reply.sent should read from response.writableEnded if it is defined', t =>
|
|
|
1935
1940
|
})
|
|
1936
1941
|
|
|
1937
1942
|
test('redirect to an invalid URL should not crash the server', async t => {
|
|
1938
|
-
const fastify =
|
|
1943
|
+
const fastify = Fastify()
|
|
1939
1944
|
fastify.route({
|
|
1940
1945
|
method: 'GET',
|
|
1941
1946
|
url: '/redirect',
|
|
@@ -1988,7 +1993,7 @@ test('redirect to an invalid URL should not crash the server', async t => {
|
|
|
1988
1993
|
})
|
|
1989
1994
|
|
|
1990
1995
|
test('invalid response headers should not crash the server', async t => {
|
|
1991
|
-
const fastify =
|
|
1996
|
+
const fastify = Fastify()
|
|
1992
1997
|
fastify.route({
|
|
1993
1998
|
method: 'GET',
|
|
1994
1999
|
url: '/bad-headers',
|
|
@@ -2021,7 +2026,7 @@ test('invalid response headers should not crash the server', async t => {
|
|
|
2021
2026
|
})
|
|
2022
2027
|
|
|
2023
2028
|
test('invalid response headers when sending back an error', async t => {
|
|
2024
|
-
const fastify =
|
|
2029
|
+
const fastify = Fastify()
|
|
2025
2030
|
fastify.route({
|
|
2026
2031
|
method: 'GET',
|
|
2027
2032
|
url: '/bad-headers',
|
|
@@ -2050,7 +2055,7 @@ test('invalid response headers when sending back an error', async t => {
|
|
|
2050
2055
|
})
|
|
2051
2056
|
|
|
2052
2057
|
test('invalid response headers and custom error handler', async t => {
|
|
2053
|
-
const fastify =
|
|
2058
|
+
const fastify = Fastify()
|
|
2054
2059
|
fastify.route({
|
|
2055
2060
|
method: 'GET',
|
|
2056
2061
|
url: '/bad-headers',
|
|
@@ -2082,3 +2087,35 @@ test('invalid response headers and custom error handler', async t => {
|
|
|
2082
2087
|
|
|
2083
2088
|
await fastify.close()
|
|
2084
2089
|
})
|
|
2090
|
+
|
|
2091
|
+
test('reply.send will intercept ERR_HTTP_HEADERS_SENT and log an error message', t => {
|
|
2092
|
+
t.plan(2)
|
|
2093
|
+
|
|
2094
|
+
const response = new Writable()
|
|
2095
|
+
Object.assign(response, {
|
|
2096
|
+
setHeader: () => {},
|
|
2097
|
+
hasHeader: () => false,
|
|
2098
|
+
getHeader: () => undefined,
|
|
2099
|
+
writeHead: () => {
|
|
2100
|
+
const err = new Error('kaboom')
|
|
2101
|
+
err.code = 'ERR_HTTP_HEADERS_SENT'
|
|
2102
|
+
throw err
|
|
2103
|
+
},
|
|
2104
|
+
write: () => {},
|
|
2105
|
+
headersSent: true
|
|
2106
|
+
})
|
|
2107
|
+
|
|
2108
|
+
const log = {
|
|
2109
|
+
warn: (msg) => {
|
|
2110
|
+
t.equal(msg, 'Reply was already sent, did you forget to "return reply" in the "/hello" (GET) route?')
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
const reply = new Reply(response, { [kRouteContext]: { onSend: null }, raw: { url: '/hello', method: 'GET' } }, log)
|
|
2115
|
+
|
|
2116
|
+
try {
|
|
2117
|
+
reply.send('')
|
|
2118
|
+
} catch (err) {
|
|
2119
|
+
t.equal(err.code, 'ERR_HTTP_HEADERS_SENT')
|
|
2120
|
+
}
|
|
2121
|
+
})
|