fastify 4.19.1 → 4.20.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/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 +38 -0
- package/fastify.d.ts +3 -2
- package/fastify.js +51 -24
- package/lib/context.js +6 -0
- package/lib/errors.js +50 -19
- 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 +3 -9
- 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 -7
- package/test/500s.test.js +22 -0
- package/test/childLoggerFactory.test.js +91 -0
- package/test/custom-http-server.test.js +42 -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 +49 -43
- 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/server.test.js +64 -2
- package/test/types/errors.test-d.ts +82 -0
- package/test/types/fastify.test-d.ts +4 -0
- package/test/types/hooks.test-d.ts +65 -64
- package/test/types/instance.test-d.ts +139 -0
- package/test/types/reply.test-d.ts +9 -8
- package/test/types/request.test-d.ts +17 -18
- package/test/types/route.test-d.ts +10 -7
- package/test/types/type-provider.test-d.ts +4 -0
- package/types/context.d.ts +3 -3
- package/types/errors.d.ts +29 -23
- package/types/instance.d.ts +39 -7
- package/types/logger.d.ts +25 -0
- package/types/reply.d.ts +10 -5
- package/types/request.d.ts +5 -5
- package/types/route.d.ts +8 -7
|
@@ -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 {
|
|
@@ -1503,7 +1509,7 @@ test('should throw error when passing falsy value to reply.sent', t => {
|
|
|
1503
1509
|
|
|
1504
1510
|
test('should throw error when attempting to set reply.sent more than once', t => {
|
|
1505
1511
|
t.plan(4)
|
|
1506
|
-
const fastify =
|
|
1512
|
+
const fastify = Fastify()
|
|
1507
1513
|
|
|
1508
1514
|
fastify.get('/', function (req, reply) {
|
|
1509
1515
|
reply.sent = true
|
|
@@ -1525,7 +1531,7 @@ test('should throw error when attempting to set reply.sent more than once', t =>
|
|
|
1525
1531
|
|
|
1526
1532
|
test('should not throw error when attempting to set reply.sent if the underlining request was sent', t => {
|
|
1527
1533
|
t.plan(3)
|
|
1528
|
-
const fastify =
|
|
1534
|
+
const fastify = Fastify()
|
|
1529
1535
|
|
|
1530
1536
|
fastify.get('/', function (req, reply) {
|
|
1531
1537
|
reply.raw.end()
|
|
@@ -1549,7 +1555,7 @@ test('reply.getResponseTime() should return 0 before the timer is initialised on
|
|
|
1549
1555
|
|
|
1550
1556
|
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
1557
|
t.plan(1)
|
|
1552
|
-
const fastify =
|
|
1558
|
+
const fastify = Fastify()
|
|
1553
1559
|
fastify.route({
|
|
1554
1560
|
method: 'GET',
|
|
1555
1561
|
url: '/',
|
|
@@ -1568,7 +1574,7 @@ test('reply.getResponseTime() should return a number greater than 0 after the ti
|
|
|
1568
1574
|
|
|
1569
1575
|
test('reply.getResponseTime() should return the time since a request started while inflight', t => {
|
|
1570
1576
|
t.plan(1)
|
|
1571
|
-
const fastify =
|
|
1577
|
+
const fastify = Fastify()
|
|
1572
1578
|
fastify.route({
|
|
1573
1579
|
method: 'GET',
|
|
1574
1580
|
url: '/',
|
|
@@ -1591,7 +1597,7 @@ test('reply.getResponseTime() should return the time since a request started whi
|
|
|
1591
1597
|
|
|
1592
1598
|
test('reply.getResponseTime() should return the same value after a request is finished', t => {
|
|
1593
1599
|
t.plan(1)
|
|
1594
|
-
const fastify =
|
|
1600
|
+
const fastify = Fastify()
|
|
1595
1601
|
fastify.route({
|
|
1596
1602
|
method: 'GET',
|
|
1597
1603
|
url: '/',
|
|
@@ -1610,7 +1616,7 @@ test('reply.getResponseTime() should return the same value after a request is fi
|
|
|
1610
1616
|
|
|
1611
1617
|
test('reply should use the custom serializer', t => {
|
|
1612
1618
|
t.plan(4)
|
|
1613
|
-
const fastify =
|
|
1619
|
+
const fastify = Fastify()
|
|
1614
1620
|
fastify.setReplySerializer((payload, statusCode) => {
|
|
1615
1621
|
t.same(payload, { foo: 'bar' })
|
|
1616
1622
|
t.equal(statusCode, 200)
|
|
@@ -1638,7 +1644,7 @@ test('reply should use the custom serializer', t => {
|
|
|
1638
1644
|
test('reply should use the right serializer in encapsulated context', t => {
|
|
1639
1645
|
t.plan(9)
|
|
1640
1646
|
|
|
1641
|
-
const fastify =
|
|
1647
|
+
const fastify = Fastify()
|
|
1642
1648
|
fastify.setReplySerializer((payload) => {
|
|
1643
1649
|
t.same(payload, { foo: 'bar' })
|
|
1644
1650
|
payload.foo = 'bar bar'
|
|
@@ -1707,7 +1713,7 @@ test('reply should use the right serializer in encapsulated context', t => {
|
|
|
1707
1713
|
test('reply should use the right serializer in deep encapsulated context', t => {
|
|
1708
1714
|
t.plan(8)
|
|
1709
1715
|
|
|
1710
|
-
const fastify =
|
|
1716
|
+
const fastify = Fastify()
|
|
1711
1717
|
|
|
1712
1718
|
fastify.route({
|
|
1713
1719
|
method: 'GET',
|
|
@@ -1771,7 +1777,7 @@ test('reply should use the right serializer in deep encapsulated context', t =>
|
|
|
1771
1777
|
test('reply should use the route serializer', t => {
|
|
1772
1778
|
t.plan(3)
|
|
1773
1779
|
|
|
1774
|
-
const fastify =
|
|
1780
|
+
const fastify = Fastify()
|
|
1775
1781
|
fastify.setReplySerializer(() => {
|
|
1776
1782
|
t.fail('this serializer should not be executed')
|
|
1777
1783
|
})
|
|
@@ -1802,7 +1808,7 @@ test('reply should use the route serializer', t => {
|
|
|
1802
1808
|
test('cannot set the replySerializer when the server is running', t => {
|
|
1803
1809
|
t.plan(2)
|
|
1804
1810
|
|
|
1805
|
-
const fastify =
|
|
1811
|
+
const fastify = Fastify()
|
|
1806
1812
|
t.teardown(fastify.close.bind(fastify))
|
|
1807
1813
|
|
|
1808
1814
|
fastify.listen({ port: 0 }, err => {
|
|
@@ -1819,7 +1825,7 @@ test('cannot set the replySerializer when the server is running', t => {
|
|
|
1819
1825
|
test('reply should not call the custom serializer for errors and not found', t => {
|
|
1820
1826
|
t.plan(9)
|
|
1821
1827
|
|
|
1822
|
-
const fastify =
|
|
1828
|
+
const fastify = Fastify()
|
|
1823
1829
|
fastify.setReplySerializer((payload, statusCode) => {
|
|
1824
1830
|
t.same(payload, { foo: 'bar' })
|
|
1825
1831
|
t.equal(statusCode, 200)
|
|
@@ -1935,7 +1941,7 @@ test('reply.sent should read from response.writableEnded if it is defined', t =>
|
|
|
1935
1941
|
})
|
|
1936
1942
|
|
|
1937
1943
|
test('redirect to an invalid URL should not crash the server', async t => {
|
|
1938
|
-
const fastify =
|
|
1944
|
+
const fastify = Fastify()
|
|
1939
1945
|
fastify.route({
|
|
1940
1946
|
method: 'GET',
|
|
1941
1947
|
url: '/redirect',
|
|
@@ -1988,7 +1994,7 @@ test('redirect to an invalid URL should not crash the server', async t => {
|
|
|
1988
1994
|
})
|
|
1989
1995
|
|
|
1990
1996
|
test('invalid response headers should not crash the server', async t => {
|
|
1991
|
-
const fastify =
|
|
1997
|
+
const fastify = Fastify()
|
|
1992
1998
|
fastify.route({
|
|
1993
1999
|
method: 'GET',
|
|
1994
2000
|
url: '/bad-headers',
|
|
@@ -2021,7 +2027,7 @@ test('invalid response headers should not crash the server', async t => {
|
|
|
2021
2027
|
})
|
|
2022
2028
|
|
|
2023
2029
|
test('invalid response headers when sending back an error', async t => {
|
|
2024
|
-
const fastify =
|
|
2030
|
+
const fastify = Fastify()
|
|
2025
2031
|
fastify.route({
|
|
2026
2032
|
method: 'GET',
|
|
2027
2033
|
url: '/bad-headers',
|
|
@@ -2050,7 +2056,7 @@ test('invalid response headers when sending back an error', async t => {
|
|
|
2050
2056
|
})
|
|
2051
2057
|
|
|
2052
2058
|
test('invalid response headers and custom error handler', async t => {
|
|
2053
|
-
const fastify =
|
|
2059
|
+
const fastify = Fastify()
|
|
2054
2060
|
fastify.route({
|
|
2055
2061
|
method: 'GET',
|
|
2056
2062
|
url: '/bad-headers',
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { test } = require('tap')
|
|
4
|
+
const { reqIdGenFactory } = require('../../lib/reqIdGenFactory')
|
|
5
|
+
|
|
6
|
+
test('should create incremental ids deterministically', t => {
|
|
7
|
+
t.plan(9999)
|
|
8
|
+
const reqIdGen = reqIdGenFactory()
|
|
9
|
+
|
|
10
|
+
for (let i = 1; i < 1e4; ++i) {
|
|
11
|
+
t.equal(reqIdGen(), 'req-' + i.toString(36))
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
test('should have prefix "req-"', t => {
|
|
16
|
+
t.plan(1)
|
|
17
|
+
const reqIdGen = reqIdGenFactory()
|
|
18
|
+
|
|
19
|
+
t.ok(reqIdGen().startsWith('req-'))
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('different id generator functions should have separate internal counters', t => {
|
|
23
|
+
t.plan(5)
|
|
24
|
+
const reqIdGenA = reqIdGenFactory()
|
|
25
|
+
const reqIdGenB = reqIdGenFactory()
|
|
26
|
+
|
|
27
|
+
t.equal(reqIdGenA(), 'req-1')
|
|
28
|
+
t.equal(reqIdGenA(), 'req-2')
|
|
29
|
+
t.equal(reqIdGenB(), 'req-1')
|
|
30
|
+
t.equal(reqIdGenA(), 'req-3')
|
|
31
|
+
t.equal(reqIdGenB(), 'req-2')
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
test('should start counting with 1', t => {
|
|
35
|
+
t.plan(1)
|
|
36
|
+
const reqIdGen = reqIdGenFactory()
|
|
37
|
+
|
|
38
|
+
t.equal(reqIdGen(), 'req-1')
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('should handle requestIdHeader and return provided id in header', t => {
|
|
42
|
+
t.plan(1)
|
|
43
|
+
|
|
44
|
+
const reqIdGen = reqIdGenFactory('id')
|
|
45
|
+
|
|
46
|
+
t.equal(reqIdGen({ headers: { id: '1337' } }), '1337')
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('should handle requestIdHeader and fallback if id is not provided in header', t => {
|
|
50
|
+
t.plan(1)
|
|
51
|
+
|
|
52
|
+
const reqIdGen = reqIdGenFactory('id')
|
|
53
|
+
|
|
54
|
+
t.equal(reqIdGen({ headers: { notId: '1337' } }), 'req-1')
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('should handle requestIdHeader and increment internal counter if no header was provided', t => {
|
|
58
|
+
t.plan(4)
|
|
59
|
+
|
|
60
|
+
const reqIdGen = reqIdGenFactory('id')
|
|
61
|
+
|
|
62
|
+
t.equal(reqIdGen({ headers: {} }), 'req-1')
|
|
63
|
+
t.equal(reqIdGen({ headers: {} }), 'req-2')
|
|
64
|
+
t.equal(reqIdGen({ headers: { id: '1337' } }), '1337')
|
|
65
|
+
t.equal(reqIdGen({ headers: {} }), 'req-3')
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
test('should use optGenReqId to generate ids', t => {
|
|
69
|
+
t.plan(4)
|
|
70
|
+
|
|
71
|
+
let i = 1
|
|
72
|
+
let gotCalled = false
|
|
73
|
+
function optGenReqId () {
|
|
74
|
+
gotCalled = true
|
|
75
|
+
return (i++).toString(16)
|
|
76
|
+
}
|
|
77
|
+
const reqIdGen = reqIdGenFactory(undefined, optGenReqId)
|
|
78
|
+
|
|
79
|
+
t.equal(gotCalled, false)
|
|
80
|
+
t.equal(reqIdGen(), '1')
|
|
81
|
+
t.equal(gotCalled, true)
|
|
82
|
+
t.equal(reqIdGen(), '2')
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('should use optGenReqId to generate ids if requestIdHeader is used but not provided', t => {
|
|
86
|
+
t.plan(4)
|
|
87
|
+
|
|
88
|
+
let i = 1
|
|
89
|
+
let gotCalled = false
|
|
90
|
+
function optGenReqId () {
|
|
91
|
+
gotCalled = true
|
|
92
|
+
return (i++).toString(16)
|
|
93
|
+
}
|
|
94
|
+
const reqIdGen = reqIdGenFactory('reqId', optGenReqId)
|
|
95
|
+
|
|
96
|
+
t.equal(gotCalled, false)
|
|
97
|
+
t.equal(reqIdGen({ headers: {} }), '1')
|
|
98
|
+
t.equal(gotCalled, true)
|
|
99
|
+
t.equal(reqIdGen({ headers: {} }), '2')
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
test('should not use optGenReqId to generate ids if requestIdHeader is used and provided', t => {
|
|
103
|
+
t.plan(2)
|
|
104
|
+
|
|
105
|
+
function optGenReqId () {
|
|
106
|
+
t.fail()
|
|
107
|
+
}
|
|
108
|
+
const reqIdGen = reqIdGenFactory('reqId', optGenReqId)
|
|
109
|
+
|
|
110
|
+
t.equal(reqIdGen({ headers: { reqId: 'r1' } }), 'r1')
|
|
111
|
+
t.equal(reqIdGen({ headers: { reqId: 'r2' } }), 'r2')
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
test('should fallback to use optGenReqId to generate ids if requestIdHeader is sometimes provided', t => {
|
|
115
|
+
t.plan(4)
|
|
116
|
+
|
|
117
|
+
let i = 1
|
|
118
|
+
let gotCalled = false
|
|
119
|
+
function optGenReqId () {
|
|
120
|
+
gotCalled = true
|
|
121
|
+
return (i++).toString(16)
|
|
122
|
+
}
|
|
123
|
+
const reqIdGen = reqIdGenFactory('reqId', optGenReqId)
|
|
124
|
+
|
|
125
|
+
t.equal(reqIdGen({ headers: { reqId: 'r1' } }), 'r1')
|
|
126
|
+
t.equal(gotCalled, false)
|
|
127
|
+
t.equal(reqIdGen({ headers: {} }), '1')
|
|
128
|
+
t.equal(gotCalled, true)
|
|
129
|
+
})
|