diff --git a/lib/read.js b/lib/read.js index eee8b111..51888c65 100644 --- a/lib/read.js +++ b/lib/read.js @@ -23,6 +23,12 @@ var zlib = require('node:zlib') module.exports = read +/** + * @const + * whether current node version has zstandard support + */ +const hasZstandardSupport = 'createZstdDecompress' in zlib + /** * Read a request into a buffer and parse. * @@ -184,12 +190,16 @@ function createDecompressionStream (encoding, debug) { case 'br': debug('brotli decompress body') return zlib.createBrotliDecompress() - default: - throw createError(415, 'unsupported content encoding "' + encoding + '"', { - encoding: encoding, - type: 'encoding.unsupported' - }) + case 'zstd': + if (hasZstandardSupport) { + debug('zstd decompress body') + return zlib.createZstdDecompress() + } } + throw createError(415, 'unsupported content encoding "' + encoding + '"', { + encoding: encoding, + type: 'encoding.unsupported' + }) } /** diff --git a/test/json.js b/test/json.js index e679ac57..2b8275ea 100644 --- a/test/json.js +++ b/test/json.js @@ -3,10 +3,15 @@ var assert = require('node:assert') var AsyncLocalStorage = require('node:async_hooks').AsyncLocalStorage var http = require('node:http') +const zlib = require('node:zlib') var request = require('supertest') var bodyParser = require('..') +const hasZstandardSupport = 'createZstdDecompress' in zlib +const zstandardit = hasZstandardSupport ? it : it.skip +const nozstandardit = !hasZstandardSupport ? it : it.skip + describe('bodyParser.json()', function () { it('should parse JSON', function (done) { request(createServer()) @@ -686,6 +691,24 @@ describe('bodyParser.json()', function () { test.expect(200, '{"name":"论"}', done) }) + zstandardit('should support zstandard encoding', function (done) { + const server = createServer({ experimentalZstd: true, limit: '1kb' }) + var test = request(server).post('/') + test.set('Content-Encoding', 'zstd') + test.set('Content-Type', 'application/json') + test.write(Buffer.from('28b52ffd200e7100007b226e616d65223a22e8aeba227d', 'hex')) + test.expect(200, '{"name":"论"}', done) + }) + + nozstandardit('should throw 415 if there\'s no zstandard support', function (done) { + const server = createServer({ experimentalZstd: true, limit: '1kb' }) + var test = request(server).post('/') + test.set('Content-Encoding', 'zstd') + test.set('Content-Type', 'application/json') + test.write(Buffer.from('28b52ffd200e7100007b226e616d65223a22e8aeba227d', 'hex')) + test.expect(415, '[encoding.unsupported] unsupported content encoding "zstd"', done) + }) + it('should be case-insensitive', function (done) { var test = request(this.server).post('/') test.set('Content-Encoding', 'GZIP') diff --git a/test/raw.js b/test/raw.js index 033a97cb..d52bae83 100644 --- a/test/raw.js +++ b/test/raw.js @@ -3,10 +3,15 @@ var assert = require('node:assert') var AsyncLocalStorage = require('node:async_hooks').AsyncLocalStorage var http = require('node:http') +const zlib = require('node:zlib') var request = require('supertest') var bodyParser = require('..') +const hasZstandardSupport = 'createZstdDecompress' in zlib +const zstandardit = hasZstandardSupport ? it : it.skip +const nozstandardit = !hasZstandardSupport ? it : it.skip + describe('bodyParser.raw()', function () { before(function () { this.server = createServer() @@ -458,6 +463,24 @@ describe('bodyParser.raw()', function () { test.expect(200, 'buf:6e616d653de8aeba', done) }) + zstandardit('should support zstandard encoding', function (done) { + const server = createServer({ experimentalZstd: true, limit: '10kb' }) + var test = request(server).post('/') + test.set('Content-Encoding', 'zstd') + test.set('Content-Type', 'application/octet-stream') + test.write(Buffer.from('28b52ffd20084100006e616d653de8aeba', 'hex')) + test.expect(200, 'buf:6e616d653de8aeba', done) + }) + + nozstandardit('should throw 415 if there\'s no zstandard support', function (done) { + const server = createServer({ experimentalZstd: true, limit: '10kb' }) + var test = request(server).post('/') + test.set('Content-Encoding', 'zstd') + test.set('Content-Type', 'application/octet-stream') + test.write(Buffer.from('28b52ffd20084100006e616d653de8aeba', 'hex')) + test.expect(415, '[encoding.unsupported] unsupported content encoding "zstd"', done) + }) + it('should be case-insensitive', function (done) { var test = request(this.server).post('/') test.set('Content-Encoding', 'GZIP') diff --git a/test/text.js b/test/text.js index 2b67aa95..209e0424 100644 --- a/test/text.js +++ b/test/text.js @@ -3,10 +3,15 @@ var assert = require('node:assert') var AsyncLocalStorage = require('node:async_hooks').AsyncLocalStorage var http = require('node:http') +const zlib = require('node:zlib') var request = require('supertest') var bodyParser = require('..') +const hasZstandardSupport = 'createZstdDecompress' in zlib +const zstandardit = hasZstandardSupport ? it : it.skip +const nozstandardit = !hasZstandardSupport ? it : it.skip + describe('bodyParser.text()', function () { before(function () { this.server = createServer() @@ -528,6 +533,24 @@ describe('bodyParser.text()', function () { test.expect(200, '"name is 论"', done) }) + zstandardit('should support zstandard encoding', function (done) { + const server = createServer({ experimentalZstd: true, limit: '10kb' }) + var test = request(server).post('/') + test.set('Content-Encoding', 'zstd') + test.set('Content-Type', 'text/plain') + test.write(Buffer.from('28b52ffd200b5900006e616d6520697320e8aeba', 'hex')) + test.expect(200, '"name is 论"', done) + }) + + nozstandardit('should throw 415 if there\'s no zstandard support', function (done) { + const server = createServer({ experimentalZstd: true, limit: '10kb' }) + var test = request(server).post('/') + test.set('Content-Encoding', 'zstd') + test.set('Content-Type', 'text/plain') + test.write(Buffer.from('28b52ffd200b5900006e616d6520697320e8aeba', 'hex')) + test.expect(415, '[encoding.unsupported] unsupported content encoding "zstd"', done) + }) + it('should be case-insensitive', function (done) { var test = request(this.server).post('/') test.set('Content-Encoding', 'GZIP') diff --git a/test/urlencoded.js b/test/urlencoded.js index d9e1c5bd..576174f5 100644 --- a/test/urlencoded.js +++ b/test/urlencoded.js @@ -3,10 +3,15 @@ var assert = require('node:assert') var AsyncLocalStorage = require('node:async_hooks').AsyncLocalStorage var http = require('node:http') +const zlib = require('node:zlib') var request = require('supertest') var bodyParser = require('..') +const hasZstandardSupport = 'createZstdDecompress' in zlib +const zstandardit = hasZstandardSupport ? it : it.skip +const nozstandardit = !hasZstandardSupport ? it : it.skip + describe('bodyParser.urlencoded()', function () { before(function () { this.server = createServer() @@ -906,6 +911,24 @@ describe('bodyParser.urlencoded()', function () { test.expect(200, '{"name":"论"}', done) }) + zstandardit('should support zstandard encoding', function (done) { + const server = createServer({ experimentalZstd: true }) + var test = request(server).post('/') + test.set('Content-Encoding', 'zstd') + test.set('Content-Type', 'application/x-www-form-urlencoded') + test.write(Buffer.from('28b52ffd20084100006e616d653de8aeba', 'hex')) + test.expect(200, '{"name":"论"}', done) + }) + + nozstandardit('should throw 415 if there\'s no zstandard support', function (done) { + const server = createServer({ experimentalZstd: true }) + var test = request(server).post('/') + test.set('Content-Encoding', 'zstd') + test.set('Content-Type', 'application/x-www-form-urlencoded') + test.write(Buffer.from('28b52ffd20084100006e616d653de8aeba', 'hex')) + test.expect(415, '[encoding.unsupported] unsupported content encoding "zstd"', done) + }) + it('should be case-insensitive', function (done) { var test = request(this.server).post('/') test.set('Content-Encoding', 'GZIP')