summaryrefslogtreecommitdiffstats
path: root/fastify-busboy/test/dicer-headerparser.test.js
diff options
context:
space:
mode:
Diffstat (limited to 'fastify-busboy/test/dicer-headerparser.test.js')
-rw-r--r--fastify-busboy/test/dicer-headerparser.test.js192
1 files changed, 192 insertions, 0 deletions
diff --git a/fastify-busboy/test/dicer-headerparser.test.js b/fastify-busboy/test/dicer-headerparser.test.js
new file mode 100644
index 0000000..73da283
--- /dev/null
+++ b/fastify-busboy/test/dicer-headerparser.test.js
@@ -0,0 +1,192 @@
+'use strict'
+
+const { test } = require('tap')
+const HeaderParser = require('../deps/dicer/lib/HeaderParser')
+
+test('dicer-headerparser', t => {
+ const DCRLF = '\r\n\r\n'
+ const MAXED_BUFFER = Buffer.allocUnsafe(128 * 1024)
+ MAXED_BUFFER.fill(0x41) // 'A'
+
+ const tests = [
+ {
+ source: DCRLF,
+ expected: {},
+ what: 'No header'
+ },
+ {
+ source: ['Content-Type:\t text/plain',
+ 'Content-Length:0'
+ ].join('\r\n') + DCRLF,
+ expected: { 'content-type': [' text/plain'], 'content-length': ['0'] },
+ what: 'Value spacing'
+ },
+ {
+ source: ['Content-Type:\t text/plain',
+ 'Content-Length:0'
+ ].join('\r\n') + DCRLF,
+ cfg: {
+ maxHeaderPairs: 0
+ },
+ expected: {},
+ what: 'should enforce maxHeaderPairs of 0'
+ },
+ {
+ source: ['Content-Type:\t text/plain',
+ 'Content-Length:0'
+ ].join('\r\n') + DCRLF,
+ cfg: {
+ maxHeaderPairs: 1
+ },
+ expected: { 'content-type': [' text/plain'] },
+ what: 'should enforce maxHeaderPairs of 1'
+ },
+ {
+ source: ['Content-Type:\r\n text/plain',
+ 'Foo:\r\n bar\r\n baz'
+ ].join('\r\n') + DCRLF,
+ expected: {},
+ cfg: {
+ maxHeaderSize: 0
+ },
+ what: 'should enforce maxHeaderSize of 0'
+ },
+ {
+ source: ['Content-Type:\r\n text/plain',
+ 'Foo:\r\n bar\r\n baz'
+ ].join('\r\n') + DCRLF,
+ expected: { 'content-type': [' text/plai'] },
+ cfg: {
+ maxHeaderSize: 25
+ },
+ what: 'should enforce maxHeaderSize of 25'
+ },
+ {
+ source: ['Content-Type:\r\n text/plain',
+ 'Foo:\r\n bar\r\n baz'
+ ].join('\r\n') + DCRLF,
+ expected: { 'content-type': [' text/plain'] },
+ cfg: {
+ maxHeaderSize: 31
+ },
+ what: 'should enforce maxHeaderSize of 31 and ignore the second header'
+ },
+ {
+ source: ['Content-Type:\r\n text/plain',
+ 'Foo:\r\n bar\r\n baz'
+ ].join('\r\n') + DCRLF,
+ expected: { 'content-type': [' text/plain'], foo: [''] },
+ cfg: {
+ maxHeaderSize: 32
+ },
+ what: 'should enforce maxHeaderSize of 32 and only add key of second header'
+ },
+ {
+ source: ['Content-Type:\r\n text/plain',
+ 'Foo:\r\n bar\r\n baz'
+ ].join('\r\n') + DCRLF,
+ expected: { 'content-type': [' text/plain'], foo: ['\r'] },
+ cfg: {
+ maxHeaderSize: 33
+ },
+ what: 'should enforce maxHeaderSize of 32 and get only first character of second pair'
+ },
+ {
+ source: ['Content-Type:\r\n text/plain',
+ ' : '
+ ].join('\r\n') + DCRLF,
+ expected: { 'content-type': [' text/plain : '] },
+ what: 'should not break if invalid header pair (colon exists but empty key and value) is provided'
+ },
+ {
+ source: ['Content-Type:\r\n text/plain',
+ 'FoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobaz'
+ ].join('\r\n') + DCRLF,
+ expected: { 'content-type': [' text/plain'] },
+ what: 'should not break if invalid header pair (no distinctive colon) is provided'
+ },
+ {
+ source: ['Content-Type:\r\n text/plain',
+ ':FoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobazFoobaz'
+ ].join('\r\n') + DCRLF,
+ expected: { 'content-type': [' text/plain'] },
+ what: 'should not break if invalid header pair (no key) is provided'
+ },
+ {
+ source: ['Content-Type:\t text/plain',
+ 'Content-Length:0'
+ ].join('\r\n') + DCRLF,
+ cfg: {
+ maxHeaderPairs: 2
+ },
+ expected: { 'content-type': [' text/plain'], 'content-length': ['0'] },
+ what: 'should enforce maxHeaderPairs of 2'
+ },
+ {
+ source: ['Content-Type:\r\n text/plain',
+ 'Foo:\r\n bar\r\n baz'
+ ].join('\r\n') + DCRLF,
+ expected: { 'content-type': [' text/plain'], foo: [' bar baz'] },
+ what: 'Folded values'
+ },
+ {
+ source: [
+ 'Foo: bar',
+ 'Foo: baz'
+ ].join('\r\n') + DCRLF,
+ expected: { foo: ['bar', 'baz'] },
+ what: 'Folded values'
+ },
+ {
+ source: ['Content-Type:',
+ 'Foo: '
+ ].join('\r\n') + DCRLF,
+ expected: { 'content-type': [''], foo: [''] },
+ what: 'Empty values'
+ },
+ {
+ source: MAXED_BUFFER.toString('ascii') + DCRLF,
+ expected: {},
+ what: 'Max header size (single chunk)'
+ },
+ {
+ source: ['ABCDEFGHIJ', MAXED_BUFFER.toString('ascii'), DCRLF],
+ expected: {},
+ what: 'Max header size (multiple chunks #1)'
+ },
+ {
+ source: [MAXED_BUFFER.toString('ascii'), MAXED_BUFFER.toString('ascii'), DCRLF],
+ expected: {},
+ what: 'Max header size (multiple chunk #2)'
+ }
+ ]
+
+ t.plan(tests.length)
+
+ tests.forEach(function (v) {
+ t.test(v.what, t => {
+ t.plan(4)
+
+ const cfg = {
+ ...v.cfg
+ }
+
+ const parser = Object.keys(cfg).length ? new HeaderParser(cfg) : new HeaderParser()
+ let fired = false
+
+ parser.on('header', function (header) {
+ t.ok(!fired, `${v.what}: Header event fired more than once`)
+ fired = true
+ t.strictSame(header,
+ v.expected,
+ `${v.what}: Parsed result mismatch`)
+ })
+ if (!Array.isArray(v.source)) { v.source = [v.source] }
+ v.source.forEach(function (s) {
+ parser.push(s)
+ })
+ t.ok(fired, `${v.what}: Did not receive header from parser`)
+ t.pass()
+ })
+ })
+})