Skip to content

Commit

Permalink
Fix #21 - handle empty payloads without crashing
Browse files Browse the repository at this point in the history
Not uploading any file will cause `Buffer.byteLength` to throw an error if called with an empty array in node >= 7, which is what `concat-stream` will return if no payload is provided.

Remove `concat-stream` in favour of `bl`, which will reliably callback with Buffer instances for empty streams.
  • Loading branch information
lennym committed Nov 10, 2017
1 parent 7fd492b commit cb53f58
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 9 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ The middleware will add files to `req.files` in the following form:
// req.files:
{
fieldName: {
data: "raw file data",
data: Buffer("raw file data"),
name: "upload.txt",
encoding: "utf8",
mimetype: "text/plain",
Expand Down Expand Up @@ -77,7 +77,7 @@ If the `multi` property is set:
// req.files:
{
fieldName: [{
data: "raw file data",
data: Buffer("raw file data"),
name: "upload.txt",
encoding: "utf8",
mimetype: "text/plain",
Expand Down
5 changes: 3 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var Busboy = require('busboy'),
bytes = require('bytes'),
concat = require('concat-stream'),
bl = require('bl'),
debug = require('debug')('busboy-body-parser');

var HARDLIMIT = bytes('250mb');
Expand Down Expand Up @@ -41,7 +41,8 @@ module.exports = function (settings) {
req.body[key] = value;
});
busboy.on('file', function (key, file, name, enc, mimetype) {
file.pipe(concat(function (d) {
file.pipe(bl(function (err, d) {
if (err || !name) { return; }
var fileData = {
data: file.truncated ? null : d,
name: name,
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
"license": "MIT",
"repository": "lennym/busboy-body-parser",
"dependencies": {
"bl": "^1.2.1",
"busboy": "^0.2.9",
"bytes": "^2.0.0",
"concat-stream": "^1.4.6",
"debug": "^2.1.0"
},
"devDependencies": {
"chai": "^1.9.2",
"express": "^4.16.2",
"mocha": "^2.0.1",
"sinon": "^1.11.1",
"sinon-chai": "^2.6.0"
Expand Down
48 changes: 44 additions & 4 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ describe('multipart form parser', function () {
parser(req, res, function () {
req.files.should.have.property('key');
req.files.key.should.eql({
data: 'abc123',
data: Buffer('abc123'),
name: 'test.jpg',
encoding: 'binary',
mimetype: 'image/jpeg',
Expand Down Expand Up @@ -154,15 +154,15 @@ describe('multipart form parser', function () {
req.files.should.have.property('key');
req.files.key.should.length(2);
req.files.key[0].should.eql({
data: 'abc123',
data: Buffer('abc123'),
name: 'test.jpg',
encoding: 'binary',
mimetype: 'image/jpeg',
size: 6,
truncated: false
});
req.files.key[1].should.eql({
data: 'xyz789',
data: Buffer('xyz789'),
name: 'test2.jpg',
encoding: 'binary',
mimetype: 'image/jpeg',
Expand All @@ -172,6 +172,46 @@ describe('multipart form parser', function () {

done();
});
})
});

it('can handle empty payloads', function (done) {
var file = {
pipe: function (s) {
s.end();
// ensure 'finish' event fires after files are processed
process.nextTick(Busboy.prototype.on.withArgs('finish').args[0][1]);
},
truncated: false
};
Busboy.prototype.on.withArgs('file').yieldsAsync('key', file, '', '7bit', 'application/octet-stream');
parser(req, res, function () {
req.files.should.eql({});
done();
});
});

it('can handle empty files', function (done) {
var file = {
pipe: function (s) {
s.end();
// ensure 'finish' event fires after files are processed
process.nextTick(Busboy.prototype.on.withArgs('finish').args[0][1]);
},
truncated: false
};
Busboy.prototype.on.withArgs('file').yieldsAsync('key', file, 'test.jpg', 'binary', 'image/jpeg');
parser(req, res, function () {
req.files.should.have.property('key');
req.files.key.should.eql({
data: Buffer(''),
name: 'test.jpg',
encoding: 'binary',
mimetype: 'image/jpeg',
size: 0,
truncated: false
});
done();
});
});

});

0 comments on commit cb53f58

Please sign in to comment.