UNPKG

27.3 kBJavaScriptView Raw
1'use strict'
2
3const fs = require('fs')
4const t = require('tap')
5const test = t.test
6const semver = require('semver')
7const sget = require('simple-get').concat
8const Fastify = require('..')
9
10const jsonParser = require('fast-json-body')
11
12function plainTextParser (request, callback) {
13 var body = ''
14 request.setEncoding('utf8')
15 request.on('error', onError)
16 request.on('data', onData)
17 request.on('end', onEnd)
18 function onError (err) {
19 callback(err, null)
20 }
21 function onData (chunk) {
22 body += chunk
23 }
24 function onEnd () {
25 callback(null, body)
26 }
27}
28
29if (semver.gt(process.versions.node, '8.0.0')) {
30 require('./custom-parser-async')
31}
32test('contentTypeParser method should exist', t => {
33 t.plan(1)
34 const fastify = Fastify()
35 t.ok(fastify.addContentTypeParser)
36})
37
38test('contentTypeParser should add a custom parser', t => {
39 t.plan(3)
40 const fastify = Fastify()
41
42 fastify.post('/', (req, reply) => {
43 reply.send(req.body)
44 })
45
46 fastify.options('/', (req, reply) => {
47 reply.send(req.body)
48 })
49
50 fastify.addContentTypeParser('application/jsoff', function (req, done) {
51 jsonParser(req, function (err, body) {
52 done(err, body)
53 })
54 })
55
56 fastify.listen(0, err => {
57 t.error(err)
58
59 t.tearDown(() => fastify.close())
60
61 t.test('in POST', t => {
62 t.plan(3)
63
64 sget({
65 method: 'POST',
66 url: 'http://localhost:' + fastify.server.address().port,
67 body: '{"hello":"world"}',
68 headers: {
69 'Content-Type': 'application/jsoff'
70 }
71 }, (err, response, body) => {
72 t.error(err)
73 t.strictEqual(response.statusCode, 200)
74 t.deepEqual(body.toString(), JSON.stringify({ hello: 'world' }))
75 })
76 })
77
78 t.test('in OPTIONS', t => {
79 t.plan(3)
80
81 sget({
82 method: 'OPTIONS',
83 url: 'http://localhost:' + fastify.server.address().port,
84 body: '{"hello":"world"}',
85 headers: {
86 'Content-Type': 'application/jsoff'
87 }
88 }, (err, response, body) => {
89 t.error(err)
90 t.strictEqual(response.statusCode, 200)
91 t.deepEqual(body.toString(), JSON.stringify({ hello: 'world' }))
92 })
93 })
94 })
95})
96
97test('contentTypeParser should handle multiple custom parsers', t => {
98 t.plan(7)
99 const fastify = Fastify()
100
101 fastify.post('/', (req, reply) => {
102 reply.send(req.body)
103 })
104
105 fastify.post('/hello', (req, reply) => {
106 reply.send(req.body)
107 })
108
109 function customParser (req, done) {
110 jsonParser(req, function (err, body) {
111 done(err, body)
112 })
113 }
114
115 fastify.addContentTypeParser('application/jsoff', customParser)
116 fastify.addContentTypeParser('application/ffosj', customParser)
117
118 fastify.listen(0, err => {
119 t.error(err)
120 fastify.server.unref()
121
122 sget({
123 method: 'POST',
124 url: 'http://localhost:' + fastify.server.address().port,
125 body: '{"hello":"world"}',
126 headers: {
127 'Content-Type': 'application/jsoff'
128 }
129 }, (err, response, body) => {
130 t.error(err)
131 t.strictEqual(response.statusCode, 200)
132 t.deepEqual(body.toString(), JSON.stringify({ hello: 'world' }))
133 })
134
135 sget({
136 method: 'POST',
137 url: 'http://localhost:' + fastify.server.address().port + '/hello',
138 body: '{"hello":"world"}',
139 headers: {
140 'Content-Type': 'application/ffosj'
141 }
142 }, (err, response, body) => {
143 t.error(err)
144 t.strictEqual(response.statusCode, 200)
145 t.deepEqual(body.toString(), JSON.stringify({ hello: 'world' }))
146 })
147 })
148})
149
150test('contentTypeParser should handle an array of custom contentTypes', t => {
151 t.plan(7)
152 const fastify = Fastify()
153
154 fastify.post('/', (req, reply) => {
155 reply.send(req.body)
156 })
157
158 fastify.post('/hello', (req, reply) => {
159 reply.send(req.body)
160 })
161
162 function customParser (req, done) {
163 jsonParser(req, function (err, body) {
164 done(err, body)
165 })
166 }
167
168 fastify.addContentTypeParser(['application/jsoff', 'application/ffosj'], customParser)
169
170 fastify.listen(0, err => {
171 t.error(err)
172 fastify.server.unref()
173
174 sget({
175 method: 'POST',
176 url: 'http://localhost:' + fastify.server.address().port,
177 body: '{"hello":"world"}',
178 headers: {
179 'Content-Type': 'application/jsoff'
180 }
181 }, (err, response, body) => {
182 t.error(err)
183 t.strictEqual(response.statusCode, 200)
184 t.deepEqual(body.toString(), JSON.stringify({ hello: 'world' }))
185 })
186
187 sget({
188 method: 'POST',
189 url: 'http://localhost:' + fastify.server.address().port + '/hello',
190 body: '{"hello":"world"}',
191 headers: {
192 'Content-Type': 'application/ffosj'
193 }
194 }, (err, response, body) => {
195 t.error(err)
196 t.strictEqual(response.statusCode, 200)
197 t.deepEqual(body.toString(), JSON.stringify({ hello: 'world' }))
198 })
199 })
200})
201
202test('contentTypeParser should handle errors', t => {
203 t.plan(3)
204 const fastify = Fastify()
205
206 fastify.post('/', (req, reply) => {
207 reply.send(req.body)
208 })
209
210 fastify.addContentTypeParser('application/jsoff', function (req, done) {
211 done(new Error('kaboom!'), {})
212 })
213
214 fastify.listen(0, err => {
215 t.error(err)
216
217 sget({
218 method: 'POST',
219 url: 'http://localhost:' + fastify.server.address().port,
220 body: '{"hello":"world"}',
221 headers: {
222 'Content-Type': 'application/jsoff'
223 }
224 }, (err, response, body) => {
225 t.error(err)
226 t.strictEqual(response.statusCode, 500)
227 fastify.close()
228 })
229 })
230})
231
232test('contentTypeParser should support encapsulation', t => {
233 t.plan(6)
234 const fastify = Fastify()
235
236 fastify.register((instance, opts, next) => {
237 instance.addContentTypeParser('application/jsoff', () => {})
238 t.ok(instance.hasContentTypeParser('application/jsoff'))
239
240 instance.register((instance, opts, next) => {
241 instance.addContentTypeParser('application/ffosj', () => {})
242 t.ok(instance.hasContentTypeParser('application/jsoff'))
243 t.ok(instance.hasContentTypeParser('application/ffosj'))
244 next()
245 })
246
247 next()
248 })
249
250 fastify.ready(err => {
251 t.error(err)
252 t.notOk(fastify.hasContentTypeParser('application/jsoff'))
253 t.notOk(fastify.hasContentTypeParser('application/ffosj'))
254 })
255})
256
257test('contentTypeParser should support encapsulation, second try', t => {
258 t.plan(4)
259 const fastify = Fastify()
260
261 fastify.register((instance, opts, next) => {
262 instance.post('/', (req, reply) => {
263 reply.send(req.body)
264 })
265
266 instance.addContentTypeParser('application/jsoff', function (req, done) {
267 jsonParser(req, function (err, body) {
268 done(err, body)
269 })
270 })
271
272 next()
273 })
274
275 fastify.listen(0, err => {
276 t.error(err)
277
278 sget({
279 method: 'POST',
280 url: 'http://localhost:' + fastify.server.address().port,
281 body: '{"hello":"world"}',
282 headers: {
283 'Content-Type': 'application/jsoff'
284 }
285 }, (err, response, body) => {
286 t.error(err)
287 t.strictEqual(response.statusCode, 200)
288 t.deepEqual(body.toString(), JSON.stringify({ hello: 'world' }))
289 fastify.close()
290 })
291 })
292})
293
294test('contentTypeParser shouldn\'t support request with undefined "Content-Type"', t => {
295 t.plan(3)
296 const fastify = Fastify()
297
298 fastify.post('/', (req, reply) => {
299 reply.send(req.body)
300 })
301
302 fastify.addContentTypeParser('application/jsoff', function (req, done) {
303 jsonParser(req, function (err, body) {
304 done(err, body)
305 })
306 })
307
308 fastify.listen(0, err => {
309 t.error(err)
310
311 sget({
312 method: 'POST',
313 url: 'http://localhost:' + fastify.server.address().port,
314 body: 'unknown content type!',
315 headers: {
316 // 'Content-Type': undefined
317 }
318 }, (err, response, body) => {
319 t.error(err)
320 t.strictEqual(response.statusCode, 415)
321 fastify.close()
322 })
323 })
324})
325
326test('the content type should be a string', t => {
327 t.plan(1)
328 const fastify = Fastify()
329
330 try {
331 fastify.addContentTypeParser(null, () => {})
332 t.fail()
333 } catch (err) {
334 t.is(err.message, 'FST_ERR_CTP_INVALID_TYPE: The content type should be a string')
335 }
336})
337
338test('the content type cannot be an empty string', t => {
339 t.plan(1)
340 const fastify = Fastify()
341
342 try {
343 fastify.addContentTypeParser('', () => {})
344 t.fail()
345 } catch (err) {
346 t.is(err.message, 'FST_ERR_CTP_EMPTY_TYPE: The content type cannot be an empty string')
347 }
348})
349
350test('the content type handler should be a function', t => {
351 t.plan(1)
352 const fastify = Fastify()
353
354 try {
355 fastify.addContentTypeParser('aaa', null)
356 t.fail()
357 } catch (err) {
358 t.is(err.message, 'FST_ERR_CTP_INVALID_HANDLER: The content type handler should be a function')
359 }
360})
361
362test('catch all content type parser', t => {
363 t.plan(7)
364 const fastify = Fastify()
365
366 fastify.post('/', (req, reply) => {
367 reply.send(req.body)
368 })
369
370 fastify.addContentTypeParser('*', function (req, done) {
371 var data = ''
372 req.on('data', chunk => { data += chunk })
373 req.on('end', () => {
374 done(null, data)
375 })
376 })
377
378 fastify.listen(0, err => {
379 t.error(err)
380
381 sget({
382 method: 'POST',
383 url: 'http://localhost:' + fastify.server.address().port,
384 body: 'hello',
385 headers: {
386 'Content-Type': 'application/jsoff'
387 }
388 }, (err, response, body) => {
389 t.error(err)
390 t.strictEqual(response.statusCode, 200)
391 t.deepEqual(body.toString(), 'hello')
392
393 sget({
394 method: 'POST',
395 url: 'http://localhost:' + fastify.server.address().port,
396 body: 'hello',
397 headers: {
398 'Content-Type': 'very-weird-content-type'
399 }
400 }, (err, response, body) => {
401 t.error(err)
402 t.strictEqual(response.statusCode, 200)
403 t.deepEqual(body.toString(), 'hello')
404 fastify.close()
405 })
406 })
407 })
408})
409
410test('catch all content type parser should not interfere with other conte type parsers', t => {
411 t.plan(7)
412 const fastify = Fastify()
413
414 fastify.post('/', (req, reply) => {
415 reply.send(req.body)
416 })
417
418 fastify.addContentTypeParser('*', function (req, done) {
419 var data = ''
420 req.on('data', chunk => { data += chunk })
421 req.on('end', () => {
422 done(null, data)
423 })
424 })
425
426 fastify.addContentTypeParser('application/jsoff', function (req, done) {
427 jsonParser(req, function (err, body) {
428 done(err, body)
429 })
430 })
431
432 fastify.listen(0, err => {
433 t.error(err)
434
435 sget({
436 method: 'POST',
437 url: 'http://localhost:' + fastify.server.address().port,
438 body: '{"hello":"world"}',
439 headers: {
440 'Content-Type': 'application/jsoff'
441 }
442 }, (err, response, body) => {
443 t.error(err)
444 t.strictEqual(response.statusCode, 200)
445 t.deepEqual(body.toString(), JSON.stringify({ hello: 'world' }))
446
447 sget({
448 method: 'POST',
449 url: 'http://localhost:' + fastify.server.address().port,
450 body: 'hello',
451 headers: {
452 'Content-Type': 'very-weird-content-type'
453 }
454 }, (err, response, body) => {
455 t.error(err)
456 t.strictEqual(response.statusCode, 200)
457 t.deepEqual(body.toString(), 'hello')
458 fastify.close()
459 })
460 })
461 })
462})
463
464// Issue 492 https://github.com/fastify/fastify/issues/492
465test('\'*\' catch undefined Content-Type requests', t => {
466 t.plan(4)
467
468 const fastify = Fastify()
469
470 t.tearDown(fastify.close.bind(fastify))
471
472 fastify.addContentTypeParser('*', function (req, done) {
473 var data = ''
474 req.on('data', chunk => { data += chunk })
475 req.on('end', () => {
476 done(null, data)
477 })
478 })
479
480 fastify.post('/', (req, res) => {
481 // Needed to avoid json stringify
482 res.type('text/plain').send(req.body)
483 })
484
485 fastify.listen(0, function (err) {
486 t.error(err)
487
488 const fileStream = fs.createReadStream(__filename)
489
490 sget({
491 method: 'POST',
492 url: 'http://localhost:' + fastify.server.address().port + '/',
493 body: fileStream
494 }, (err, response, body) => {
495 t.error(err)
496 t.strictEqual(response.statusCode, 200)
497 t.strictEqual(body + '', fs.readFileSync(__filename).toString())
498 })
499 })
500})
501
502test('cannot add custom parser after binding', t => {
503 t.plan(2)
504
505 const fastify = Fastify()
506
507 t.tearDown(fastify.close.bind(fastify))
508
509 fastify.post('/', (req, res) => {
510 res.type('text/plain').send(req.body)
511 })
512
513 fastify.listen(0, function (err) {
514 t.error(err)
515
516 try {
517 fastify.addContentTypeParser('*', () => {})
518 t.fail()
519 } catch (e) {
520 t.pass()
521 }
522 })
523})
524
525test('Can override the default json parser', t => {
526 t.plan(5)
527 const fastify = Fastify()
528
529 fastify.post('/', (req, reply) => {
530 reply.send(req.body)
531 })
532
533 fastify.addContentTypeParser('application/json', function (req, done) {
534 t.ok('called')
535 jsonParser(req, function (err, body) {
536 done(err, body)
537 })
538 })
539
540 fastify.listen(0, err => {
541 t.error(err)
542
543 sget({
544 method: 'POST',
545 url: 'http://localhost:' + fastify.server.address().port,
546 body: '{"hello":"world"}',
547 headers: {
548 'Content-Type': 'application/json'
549 }
550 }, (err, response, body) => {
551 t.error(err)
552 t.strictEqual(response.statusCode, 200)
553 t.strictEqual(body.toString(), '{"hello":"world"}')
554 fastify.close()
555 })
556 })
557})
558
559test('Can override the default plain text parser', t => {
560 t.plan(5)
561 const fastify = Fastify()
562
563 fastify.post('/', (req, reply) => {
564 reply.send(req.body)
565 })
566
567 fastify.addContentTypeParser('text/plain', function (req, done) {
568 t.ok('called')
569 plainTextParser(req, function (err, body) {
570 done(err, body)
571 })
572 })
573
574 fastify.listen(0, err => {
575 t.error(err)
576
577 sget({
578 method: 'POST',
579 url: 'http://localhost:' + fastify.server.address().port,
580 body: 'hello world',
581 headers: {
582 'Content-Type': 'text/plain'
583 }
584 }, (err, response, body) => {
585 t.error(err)
586 t.strictEqual(response.statusCode, 200)
587 t.strictEqual(body.toString(), 'hello world')
588 fastify.close()
589 })
590 })
591})
592
593test('Can override the default json parser in a plugin', t => {
594 t.plan(5)
595 const fastify = Fastify()
596
597 fastify.register((instance, opts, next) => {
598 instance.addContentTypeParser('application/json', function (req, done) {
599 t.ok('called')
600 jsonParser(req, function (err, body) {
601 done(err, body)
602 })
603 })
604
605 instance.post('/', (req, reply) => {
606 reply.send(req.body)
607 })
608
609 next()
610 })
611
612 fastify.listen(0, err => {
613 t.error(err)
614
615 sget({
616 method: 'POST',
617 url: 'http://localhost:' + fastify.server.address().port,
618 body: '{"hello":"world"}',
619 headers: {
620 'Content-Type': 'application/json'
621 }
622 }, (err, response, body) => {
623 t.error(err)
624 t.strictEqual(response.statusCode, 200)
625 t.strictEqual(body.toString(), '{"hello":"world"}')
626 fastify.close()
627 })
628 })
629})
630
631test('Can\'t override the json parser multiple times', t => {
632 t.plan(1)
633 const fastify = Fastify()
634
635 fastify.addContentTypeParser('application/json', function (req, done) {
636 jsonParser(req, function (err, body) {
637 done(err, body)
638 })
639 })
640
641 try {
642 fastify.addContentTypeParser('application/json', function (req, done) {
643 t.ok('called')
644 jsonParser(req, function (err, body) {
645 done(err, body)
646 })
647 })
648 } catch (err) {
649 t.is(err.message, 'FST_ERR_CTP_ALREADY_PRESENT: Content type parser \'application/json\' already present.')
650 }
651})
652
653test('Can\'t override the plain text parser multiple times', t => {
654 t.plan(1)
655 const fastify = Fastify()
656
657 fastify.addContentTypeParser('text/plain', function (req, done) {
658 plainTextParser(req, function (err, body) {
659 done(err, body)
660 })
661 })
662
663 try {
664 fastify.addContentTypeParser('text/plain', function (req, done) {
665 t.ok('called')
666 plainTextParser(req, function (err, body) {
667 done(err, body)
668 })
669 })
670 } catch (err) {
671 t.is(err.message, 'FST_ERR_CTP_ALREADY_PRESENT: Content type parser \'text/plain\' already present.')
672 }
673})
674
675test('Should get the body as string', t => {
676 t.plan(6)
677 const fastify = Fastify()
678
679 fastify.post('/', (req, reply) => {
680 reply.send(req.body)
681 })
682
683 fastify.addContentTypeParser('application/json', { parseAs: 'string' }, function (req, body, done) {
684 t.ok('called')
685 t.ok(typeof body === 'string')
686 try {
687 var json = JSON.parse(body)
688 done(null, json)
689 } catch (err) {
690 err.statusCode = 400
691 done(err, undefined)
692 }
693 })
694
695 fastify.listen(0, err => {
696 t.error(err)
697
698 sget({
699 method: 'POST',
700 url: 'http://localhost:' + fastify.server.address().port,
701 body: '{"hello":"world"}',
702 headers: {
703 'Content-Type': 'application/json'
704 }
705 }, (err, response, body) => {
706 t.error(err)
707 t.strictEqual(response.statusCode, 200)
708 t.strictEqual(body.toString(), '{"hello":"world"}')
709 fastify.close()
710 })
711 })
712})
713
714test('Should return defined body with no custom parser defined and content type = \'text/plain\'', t => {
715 t.plan(4)
716 const fastify = Fastify()
717
718 fastify.post('/', (req, reply) => {
719 reply.send(req.body)
720 })
721
722 fastify.listen(0, err => {
723 t.error(err)
724
725 sget({
726 method: 'POST',
727 url: 'http://localhost:' + fastify.server.address().port,
728 body: 'hello world',
729 headers: {
730 'Content-Type': 'text/plain'
731 }
732 }, (err, response, body) => {
733 t.error(err)
734 t.strictEqual(response.statusCode, 200)
735 t.strictEqual(body.toString(), 'hello world')
736 fastify.close()
737 })
738 })
739})
740
741test('Should have typeof body object with no custom parser defined, no body defined and content type = \'text/plain\'', t => {
742 t.plan(4)
743 const fastify = Fastify()
744
745 fastify.post('/', (req, reply) => {
746 reply.send(req.body)
747 })
748
749 fastify.listen(0, err => {
750 t.error(err)
751
752 sget({
753 method: 'POST',
754 url: 'http://localhost:' + fastify.server.address().port,
755 headers: {
756 'Content-Type': 'text/plain'
757 }
758 }, (err, response, body) => {
759 t.error(err)
760 t.strictEqual(response.statusCode, 200)
761 t.strictEqual(typeof body, 'object')
762 fastify.close()
763 })
764 })
765})
766
767test('Should have typeof body object with no custom parser defined, null body and content type = \'text/plain\'', t => {
768 t.plan(4)
769 const fastify = Fastify()
770
771 fastify.post('/', (req, reply) => {
772 reply.send(req.body)
773 })
774
775 fastify.listen(0, err => {
776 t.error(err)
777
778 sget({
779 method: 'POST',
780 url: 'http://localhost:' + fastify.server.address().port,
781 body: null,
782 headers: {
783 'Content-Type': 'text/plain'
784 }
785 }, (err, response, body) => {
786 t.error(err)
787 t.strictEqual(response.statusCode, 200)
788 t.strictEqual(typeof body, 'object')
789 fastify.close()
790 })
791 })
792})
793
794test('Should have typeof body object with no custom parser defined, undefined body and content type = \'text/plain\'', t => {
795 t.plan(4)
796 const fastify = Fastify()
797
798 fastify.post('/', (req, reply) => {
799 reply.send(req.body)
800 })
801
802 fastify.listen(0, err => {
803 t.error(err)
804
805 sget({
806 method: 'POST',
807 url: 'http://localhost:' + fastify.server.address().port,
808 body: undefined,
809 headers: {
810 'Content-Type': 'text/plain'
811 }
812 }, (err, response, body) => {
813 t.error(err)
814 t.strictEqual(response.statusCode, 200)
815 t.strictEqual(typeof body, 'object')
816 fastify.close()
817 })
818 })
819})
820
821test('Should get the body as string', t => {
822 t.plan(6)
823 const fastify = Fastify()
824
825 fastify.post('/', (req, reply) => {
826 reply.send(req.body)
827 })
828
829 fastify.addContentTypeParser('text/plain', { parseAs: 'string' }, function (req, body, done) {
830 t.ok('called')
831 t.ok(typeof body === 'string')
832 try {
833 var plainText = body
834 done(null, plainText)
835 } catch (err) {
836 err.statusCode = 400
837 done(err, undefined)
838 }
839 })
840
841 fastify.listen(0, err => {
842 t.error(err)
843
844 sget({
845 method: 'POST',
846 url: 'http://localhost:' + fastify.server.address().port,
847 body: 'hello world',
848 headers: {
849 'Content-Type': 'text/plain'
850 }
851 }, (err, response, body) => {
852 t.error(err)
853 t.strictEqual(response.statusCode, 200)
854 t.strictEqual(body.toString(), 'hello world')
855 fastify.close()
856 })
857 })
858})
859
860test('Should get the body as buffer', t => {
861 t.plan(6)
862 const fastify = Fastify()
863
864 fastify.post('/', (req, reply) => {
865 reply.send(req.body)
866 })
867
868 fastify.addContentTypeParser('application/json', { parseAs: 'buffer' }, function (req, body, done) {
869 t.ok('called')
870 t.ok(body instanceof Buffer)
871 try {
872 var json = JSON.parse(body)
873 done(null, json)
874 } catch (err) {
875 err.statusCode = 400
876 done(err, undefined)
877 }
878 })
879
880 fastify.listen(0, err => {
881 t.error(err)
882
883 sget({
884 method: 'POST',
885 url: 'http://localhost:' + fastify.server.address().port,
886 body: '{"hello":"world"}',
887 headers: {
888 'Content-Type': 'application/json'
889 }
890 }, (err, response, body) => {
891 t.error(err)
892 t.strictEqual(response.statusCode, 200)
893 t.strictEqual(body.toString(), '{"hello":"world"}')
894 fastify.close()
895 })
896 })
897})
898
899test('Should get the body as buffer', t => {
900 t.plan(6)
901 const fastify = Fastify()
902
903 fastify.post('/', (req, reply) => {
904 reply.send(req.body)
905 })
906
907 fastify.addContentTypeParser('text/plain', { parseAs: 'buffer' }, function (req, body, done) {
908 t.ok('called')
909 t.ok(body instanceof Buffer)
910 try {
911 var plainText = body
912 done(null, plainText)
913 } catch (err) {
914 err.statusCode = 400
915 done(err, undefined)
916 }
917 })
918
919 fastify.listen(0, err => {
920 t.error(err)
921
922 sget({
923 method: 'POST',
924 url: 'http://localhost:' + fastify.server.address().port,
925 body: 'hello world',
926 headers: {
927 'Content-Type': 'text/plain'
928 }
929 }, (err, response, body) => {
930 t.error(err)
931 t.strictEqual(response.statusCode, 200)
932 t.strictEqual(body.toString(), 'hello world')
933 fastify.close()
934 })
935 })
936})
937
938test('Should parse empty bodies as a string', t => {
939 t.plan(9)
940 const fastify = Fastify()
941
942 fastify.addContentTypeParser('text/plain', { parseAs: 'string' }, (req, body, done) => {
943 t.strictEqual(body, '')
944 done(null, body)
945 })
946
947 fastify.route({
948 method: ['POST', 'DELETE'],
949 url: '/',
950 handler (request, reply) {
951 reply.send(request.body)
952 }
953 })
954
955 fastify.listen(0, err => {
956 t.error(err)
957 fastify.server.unref()
958
959 sget({
960 method: 'POST',
961 url: 'http://localhost:' + fastify.server.address().port,
962 body: '',
963 headers: {
964 'Content-Type': 'text/plain'
965 }
966 }, (err, response, body) => {
967 t.error(err)
968 t.strictEqual(response.statusCode, 200)
969 t.strictEqual(body.toString(), '')
970 })
971
972 sget({
973 method: 'DELETE',
974 url: 'http://localhost:' + fastify.server.address().port,
975 body: '',
976 headers: {
977 'Content-Type': 'text/plain',
978 'Content-Length': '0'
979 }
980 }, (err, response, body) => {
981 t.error(err)
982 t.strictEqual(response.statusCode, 200)
983 t.strictEqual(body.toString(), '')
984 })
985 })
986})
987
988test('Should parse empty bodies as a buffer', t => {
989 t.plan(6)
990 const fastify = Fastify()
991
992 fastify.post('/', (req, reply) => {
993 reply.send(req.body)
994 })
995
996 fastify.addContentTypeParser('text/plain', { parseAs: 'buffer' }, function (req, body, done) {
997 t.ok(body instanceof Buffer)
998 t.strictEqual(body.length, 0)
999 done(null, body)
1000 })
1001
1002 fastify.listen(0, err => {
1003 t.error(err)
1004
1005 sget({
1006 method: 'POST',
1007 url: 'http://localhost:' + fastify.server.address().port,
1008 body: '',
1009 headers: {
1010 'Content-Type': 'text/plain'
1011 }
1012 }, (err, response, body) => {
1013 t.error(err)
1014 t.strictEqual(response.statusCode, 200)
1015 t.strictEqual(body.length, 0)
1016 fastify.close()
1017 })
1018 })
1019})
1020
1021test('The charset should not interfere with the content type handling', t => {
1022 t.plan(5)
1023 const fastify = Fastify()
1024
1025 fastify.post('/', (req, reply) => {
1026 reply.send(req.body)
1027 })
1028
1029 fastify.addContentTypeParser('application/json', function (req, done) {
1030 t.ok('called')
1031 jsonParser(req, function (err, body) {
1032 done(err, body)
1033 })
1034 })
1035
1036 fastify.listen(0, err => {
1037 t.error(err)
1038
1039 sget({
1040 method: 'POST',
1041 url: 'http://localhost:' + fastify.server.address().port,
1042 body: '{"hello":"world"}',
1043 headers: {
1044 'Content-Type': 'application/json charset=utf-8'
1045 }
1046 }, (err, response, body) => {
1047 t.error(err)
1048 t.strictEqual(response.statusCode, 200)
1049 t.strictEqual(body.toString(), '{"hello":"world"}')
1050 fastify.close()
1051 })
1052 })
1053})
1054
1055test('Wrong parseAs parameter', t => {
1056 t.plan(1)
1057 const fastify = Fastify()
1058
1059 try {
1060 fastify.addContentTypeParser('application/json', { parseAs: 'fireworks' }, () => {})
1061 t.fail('should throw')
1062 } catch (err) {
1063 t.is(err.message, "FST_ERR_CTP_INVALID_PARSE_TYPE: The body parser can only parse your data as 'string' or 'buffer', you asked 'fireworks' which is not supported.")
1064 }
1065})
1066
1067test('Should allow defining the bodyLimit per parser', t => {
1068 t.plan(3)
1069 const fastify = Fastify()
1070 t.tearDown(() => fastify.close())
1071
1072 fastify.post('/', (req, reply) => {
1073 reply.send(req.body)
1074 })
1075
1076 fastify.addContentTypeParser(
1077 'x/foo',
1078 { parseAs: 'string', bodyLimit: 5 },
1079 function (req, body, done) {
1080 t.fail('should not be invoked')
1081 done()
1082 }
1083 )
1084
1085 fastify.listen(0, err => {
1086 t.error(err)
1087
1088 sget({
1089 method: 'POST',
1090 url: 'http://localhost:' + fastify.server.address().port,
1091 body: '1234567890',
1092 headers: {
1093 'Content-Type': 'x/foo'
1094 }
1095 }, (err, response, body) => {
1096 t.error(err)
1097 t.strictDeepEqual(JSON.parse(body.toString()), {
1098 statusCode: 413,
1099 code: 'FST_ERR_CTP_BODY_TOO_LARGE',
1100 error: 'Payload Too Large',
1101 message: 'FST_ERR_CTP_BODY_TOO_LARGE: Request body is too large'
1102 })
1103 fastify.close()
1104 })
1105 })
1106})
1107
1108test('route bodyLimit should take precedence over a custom parser bodyLimit', t => {
1109 t.plan(3)
1110 const fastify = Fastify()
1111 t.tearDown(() => fastify.close())
1112
1113 fastify.post('/', { bodyLimit: 5 }, (request, reply) => {
1114 reply.send(request.body)
1115 })
1116
1117 fastify.addContentTypeParser(
1118 'x/foo',
1119 { parseAs: 'string', bodyLimit: 100 },
1120 function (req, body, done) {
1121 t.fail('should not be invoked')
1122 done()
1123 }
1124 )
1125
1126 fastify.listen(0, err => {
1127 t.error(err)
1128
1129 sget({
1130 method: 'POST',
1131 url: 'http://localhost:' + fastify.server.address().port,
1132 body: '1234567890',
1133 headers: { 'Content-Type': 'x/foo' }
1134 }, (err, response, body) => {
1135 t.error(err)
1136 t.strictDeepEqual(JSON.parse(body.toString()), {
1137 statusCode: 413,
1138 code: 'FST_ERR_CTP_BODY_TOO_LARGE',
1139 error: 'Payload Too Large',
1140 message: 'FST_ERR_CTP_BODY_TOO_LARGE: Request body is too large'
1141 })
1142 fastify.close()
1143 })
1144 })
1145})