From ce1717e0966c8669522a8f863021ad5b1ddec263 Mon Sep 17 00:00:00 2001 From: Sumit Rai Date: Tue, 23 May 2023 14:29:00 -0700 Subject: [PATCH] feat: add an option to disable body parsing (#41) Co-authored-by: Sumit Rai --- index.js | 50 +++++++--- tests/json.js | 257 +++++++++++++++++++++++++++++--------------------- 2 files changed, 186 insertions(+), 121 deletions(-) diff --git a/index.js b/index.js index 23c6233..95efd3e 100644 --- a/index.js +++ b/index.js @@ -27,7 +27,7 @@ const fixDups = (item) => { }; const md5 = (value) => { - return crypto.createHash('md5').update(value).digest("hex"); + return crypto.createHash('md5').update(value).digest('hex'); }; const strip = (value) => { @@ -45,34 +45,47 @@ var convertParams = (item, name, data) => { }; exports.extend = function(app, options) { - if (app[key]) { return app; } + if (app[key]) { + return app; + } Object.defineProperty(app, key, { value: exports }); options = options || {}; options.immediate = false; //Remove if the user sets it + options.parseBody = typeof options.parseBody === 'boolean' ? options.parseBody : true; options.path = options.path || path.join(os.tmpdir(), 'express-busboy'); - options.strip = (options.strip && options.strip instanceof Function) ? options.strip : strip; + options.strip = options.strip && options.strip instanceof Function ? options.strip : strip; const restrictMultiple = options.restrictMultiple; - const mimeTypeLimit = options.mimeTypeLimit ? !Array.isArray(options.mimeTypeLimit) ? [options.mimeTypeLimit] : options.mimeTypeLimit : null; + const mimeTypeLimit = options.mimeTypeLimit + ? !Array.isArray(options.mimeTypeLimit) + ? [options.mimeTypeLimit] + : options.mimeTypeLimit + : null; delete options.restrictMultiple; delete options.mimeTypeLimit; - + app.use(busboy(options)); app.use((req, res, next) => { var allowUpload = true; - + req.body = req.body || {}; req.files = req.files || {}; if (req.is('json') && req.readable) { + if (!options.parseBody) { + // skip parsing body if parseBody is false + next(); + return; + } jsonBody(req, res, options, (err, body) => { req.body = body || {}; next(); }); return; } - - if (!req.busboy) { //Nothing to parse.. + + if (!req.busboy) { + //Nothing to parse.. return next(); } @@ -103,12 +116,14 @@ exports.extend = function(app, options) { file = [file]; } file.forEach((f) => { - if (!f.done) { //file is not done writing + if (!f.done) { + //file is not done writing complete = false; } }); }); - if (complete) { //all files are done writing.. + if (complete) { + //all files are done writing.. next(); } }; @@ -120,16 +135,21 @@ exports.extend = function(app, options) { const nameStripped = options.strip(name, 'name'); const filenameStripped = options.strip(filename || /*istanbul ignore next*/ '', 'filename'); const out = path.join(options.path, '/', fileUuid, '/', nameStripped, filenameStripped); - - if (mimeTypeLimit && !mimeTypeLimit.some(type => { return type === mimeType; })) { + + if ( + mimeTypeLimit && + !mimeTypeLimit.some((type) => { + return type === mimeType; + }) + ) { return file.resume(); } /*istanbul ignore next*/ if (!filename || filenameStripped === '') { - return file.on('data', () => { }); + return file.on('data', () => {}); } - + const data = { uuid: fileUuid, field: name, @@ -154,7 +174,7 @@ exports.extend = function(app, options) { file.on('limit', () => { data.truncated = true; }); - + convertParams(req.files, name, data); }); } diff --git a/tests/json.js b/tests/json.js index b156963..d1469e6 100644 --- a/tests/json.js +++ b/tests/json.js @@ -11,11 +11,14 @@ var assert = require('assert'), http = require('http'), portfinder = require('portfinder'); -var port; var app = express(); +var app2 = express(); bb.extend(app); +bb.extend(app2, { + parseBody: false +}); var base = 'http://127.0.0.1:'; -var setup = function(app) { +var setup = function(app, port) { app._server = app.listen(port); app.all('/', function(req, res) { res.send({ @@ -26,11 +29,9 @@ var setup = function(app) { }; describe('express-busboy: json', function() { - before(function(done) { portfinder.getPort(function(e, p) { - port = p; - setup(app); + setup(app, p); base += p; done(); }); @@ -41,109 +42,121 @@ describe('express-busboy: json', function() { }); it('should not populate body', function(done) { - request({ - method: 'GET', - url: base + '/', - json: true - }, function(err, res, d) { - assert.ok(d); - assert.ok(d.body); - assert.ok(d.files); - assert.equal(Object.keys(d.files).length, 0); - assert.equal(Object.keys(d.body).length, 0); - done(); - }); + request( + { + method: 'GET', + url: base + '/', + json: true + }, + function(err, res, d) { + assert.ok(d); + assert.ok(d.body); + assert.ok(d.files); + assert.equal(Object.keys(d.files).length, 0); + assert.equal(Object.keys(d.body).length, 0); + done(); + } + ); }); it('should parse post body properly', function(done) { - request({ - method: 'POST', - url: base + '/', - json: true, - form: { - obj: { one: 1, two: 2, three: 3, four: 4 }, - data: [1, 2, 3, 4], - foo: 1, - bar: 2, - baz: 3 + request( + { + method: 'POST', + url: base + '/', + json: true, + form: { + obj: { one: 1, two: 2, three: 3, four: 4 }, + data: [1, 2, 3, 4], + foo: 1, + bar: 2, + baz: 3 + } + }, + function(err, res, d) { + assert.ok(d); + assert.ok(d.body); + assert.ok(d.files); + assert.equal(Object.keys(d.files).length, 0); + assert.equal(d.body.foo, 1); + assert.equal(d.body.bar, 2); + assert.equal(d.body.baz, 3); + assert.ok(d.body.data); + assert.ok(Array.isArray(d.body.data)); + assert.equal(d.body.data[0], 1); + assert.equal(d.body.data[1], 2); + assert.equal(d.body.data[2], 3); + assert.equal(d.body.data[3], 4); + assert.ok(d.body.obj); + assert.equal(typeof d.body.obj, 'object'); + assert.equal(d.body.obj.one, 1); + assert.equal(d.body.obj.two, 2); + assert.equal(d.body.obj.three, 3); + assert.equal(d.body.obj.four, 4); + done(); } - }, function(err, res, d) { - assert.ok(d); - assert.ok(d.body); - assert.ok(d.files); - assert.equal(Object.keys(d.files).length, 0); - assert.equal(d.body.foo, 1); - assert.equal(d.body.bar, 2); - assert.equal(d.body.baz, 3); - assert.ok(d.body.data); - assert.ok(Array.isArray(d.body.data)); - assert.equal(d.body.data[0], 1); - assert.equal(d.body.data[1], 2); - assert.equal(d.body.data[2], 3); - assert.equal(d.body.data[3], 4); - assert.ok(d.body.obj); - assert.equal(typeof d.body.obj, 'object'); - assert.equal(d.body.obj.one, 1); - assert.equal(d.body.obj.two, 2); - assert.equal(d.body.obj.three, 3); - assert.equal(d.body.obj.four, 4); - done(); - }); + ); }); it('should handle bad json', function(done) { - var req = request({ - method: 'POST', - url: base + '/', - headers: { - 'content-type': 'application/json' + var req = request( + { + method: 'POST', + url: base + '/', + headers: { + 'content-type': 'application/json' + } + }, + function(err, res, d) { + d = JSON.parse(d); + assert.ok(d); + assert.ok(d.body); + assert.ok(d.files); + assert.equal(Object.keys(d.body).length, 0); + assert.equal(Object.keys(d.files).length, 0); + done(); } - }, function(err, res, d) { - d = JSON.parse(d); - assert.ok(d); - assert.ok(d.body); - assert.ok(d.files); - assert.equal(Object.keys(d.body).length, 0); - assert.equal(Object.keys(d.files).length, 0); - done(); - }); + ); req.write('{{{'); req.end(); }); it('should parse post body with JSON', function(done) { - request({ - method: 'POST', - url: base + '/', - json: { - obj: { one: 1, two: 2, three: 3, four: 4 }, - data: [1, 2, 3, 4], - foo: 1, - bar: 2, - baz: 3 + request( + { + method: 'POST', + url: base + '/', + json: { + obj: { one: 1, two: 2, three: 3, four: 4 }, + data: [1, 2, 3, 4], + foo: 1, + bar: 2, + baz: 3 + } + }, + function(err, res, d) { + assert.ok(d); + assert.ok(d.body); + assert.ok(d.files); + assert.equal(Object.keys(d.files).length, 0); + assert.equal(d.body.foo, 1); + assert.equal(d.body.bar, 2); + assert.equal(d.body.baz, 3); + assert.ok(d.body.data); + assert.ok(Array.isArray(d.body.data)); + assert.equal(d.body.data[0], 1); + assert.equal(d.body.data[1], 2); + assert.equal(d.body.data[2], 3); + assert.equal(d.body.data[3], 4); + assert.ok(d.body.obj); + assert.equal(typeof d.body.obj, 'object'); + assert.equal(d.body.obj.one, 1); + assert.equal(d.body.obj.two, 2); + assert.equal(d.body.obj.three, 3); + assert.equal(d.body.obj.four, 4); + done(); } - }, function(err, res, d) { - assert.ok(d); - assert.ok(d.body); - assert.ok(d.files); - assert.equal(Object.keys(d.files).length, 0); - assert.equal(d.body.foo, 1); - assert.equal(d.body.bar, 2); - assert.equal(d.body.baz, 3); - assert.ok(d.body.data); - assert.ok(Array.isArray(d.body.data)); - assert.equal(d.body.data[0], 1); - assert.equal(d.body.data[1], 2); - assert.equal(d.body.data[2], 3); - assert.equal(d.body.data[3], 4); - assert.ok(d.body.obj); - assert.equal(typeof d.body.obj, 'object'); - assert.equal(d.body.obj.one, 1); - assert.equal(d.body.obj.two, 2); - assert.equal(d.body.obj.three, 3); - assert.equal(d.body.obj.four, 4); - done(); - }); + ); }); it('should parse post body inline', function(done) { @@ -181,21 +194,53 @@ describe('express-busboy: json', function() { }); it('should not upload a file', function(done) { - var r = request({ - method: 'POST', - url: base + '/', - json: true - }, function(err, res, d) { - assert.ok(d); - assert.equal(d.body.foobar, 1); - assert.ok(d.body); - assert.ok(d.files); - assert.equal(Object.keys(d.files).length, 0); - done(); - }); + var r = request( + { + method: 'POST', + url: base + '/', + json: true + }, + function(err, res, d) { + assert.ok(d); + assert.equal(d.body.foobar, 1); + assert.ok(d.body); + assert.ok(d.files); + assert.equal(Object.keys(d.files).length, 0); + done(); + } + ); var form = r.form(); form.append('foobar', 1); form.append('the-file', fs.createReadStream(__filename)); }); +}); +describe('#parseBody is false', function() { + before(function(done) { + base = 'http://127.0.0.1:'; + portfinder.getPort({ port: 8001 }, function(e, p) { + setup(app2, p); + base += p; + done(); + }); + }); + after(function() { + app2._server.close(); + }); + it('should not parse post body with JSON if parseBody is false', function(done) { + request( + { + method: 'POST', + url: base + '/', + json: { + data: [1, 2, 3, 4] + } + }, + function(err, res, d) { + assert.ok(d); + assert.deepEqual(d.body, {}); + done(); + } + ); + }); });