Skip to content

Commit 441924a

Browse files
committed
add numFilesLimitHandler option
1 parent 1216f4f commit 441924a

4 files changed

Lines changed: 72 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ preserveExtension | <ul><li><code>false</code>&nbsp;**(default)**</li><li><code>
112112
abortOnLimit | <ul><li><code>false</code>&nbsp;**(default)**</li><li><code>true</code></ul> | Returns a HTTP 413 when the file is bigger than the size limit if true. Otherwise, it will add a <code>truncated = true</code> to the resulting file structure.
113113
responseOnLimit | <ul><li><code>'File size limit has been reached'</code>&nbsp;**(default)**</li><li><code>*String*</code></ul> | Response which will be send to client if file size limit exceeded when abortOnLimit set to true.
114114
limitHandler | <ul><li><code>false</code>&nbsp;**(default)**</li><li><code>function(req, res, next)</code></li></ul> | User defined limit handler which will be invoked if the file is bigger than configured limits.
115+
numFilesLimitHandler | <ul><li><code>false</code>&nbsp;**(default)**</li><li><code>function(req, res, next)</code></li></ul> | User defined handler which will be invoked if the number of files is greater than the configured `limits.files`.
115116
useTempFiles | <ul><li><code>false</code>&nbsp;**(default)**</li><li><code>true</code></ul> | By default this module uploads files into RAM. Setting this option to True turns on using temporary files instead of utilising RAM. This avoids memory overflow issues when uploading large files or in case of uploading lots of files at same time.
116117
tempFileDir | <ul><li><code>String</code>&nbsp;**(path)**</li></ul> | Path to store temporary files.<br />Used along with the <code>useTempFiles</code> option. By default this module uses 'tmp' folder in the current working directory.<br />You can use trailing slash, but it is not necessary.
117118
parseNested | <ul><li><code>false</code>&nbsp;**(default)**</li><li><code>true</code></li></ul> | By default, req.body and req.files are flattened like this: <code>{'name': 'John', 'hobbies[0]': 'Cinema', 'hobbies[1]': 'Bike'}</code><br /><br/>When this option is enabled they are parsed in order to be nested like this: <code>{'name': 'John', 'hobbies': ['Cinema', 'Bike']}</code>

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const DEFAULT_OPTIONS = {
1515
abortOnLimit: false,
1616
responseOnLimit: 'File size limit has been reached',
1717
limitHandler: false,
18+
numFilesLimitHandler: false,
1819
createParentPath: false,
1920
parseNested: false,
2021
useTempFiles: false,

lib/processMultipart.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,14 @@ module.exports = (options, req, res, next) => {
130130
uploadTimer.set();
131131
});
132132

133+
busboy.on('filesLimit', () => {
134+
debugLog(options, `Number of files limit reached`);
135+
// Run a user defined limit handler if it has been set.
136+
if (isFunc(options.numFilesLimitHandler)){
137+
return options.numFilesLimitHandler(req, res, next);
138+
}
139+
});
140+
133141
busboy.on('finish', () => {
134142
debugLog(options, `Busboy finished parsing request.`);
135143
if (options.parseNested) {

test/numFilesLimitHandler.spec.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
'use strict';
2+
3+
const path = require('path');
4+
const request = require('supertest');
5+
const assert = require('assert');
6+
const server = require('./server');
7+
const clearUploadsDir = server.clearUploadsDir;
8+
const fileDir = server.fileDir;
9+
10+
describe('Test Multiple File Upload With Files Limit Handler', function() {
11+
let app, numFilesLimitHandlerRun;
12+
13+
beforeEach(function() {
14+
clearUploadsDir();
15+
numFilesLimitHandlerRun = false;
16+
});
17+
18+
describe('Run numFilesLimitHandler on limit reached.', function(){
19+
before(function() {
20+
app = server.setup({
21+
limits: { files: 3 }, // set limit of 3 files
22+
numFilesLimitHandler: (req, res) => { // set limit handler
23+
res.writeHead(500, { Connection: 'close', 'Content-Type': 'application/json'});
24+
res.end(JSON.stringify({response: 'Too many files!'}));
25+
numFilesLimitHandlerRun = true;
26+
}
27+
});
28+
});
29+
30+
it('Runs handler when too many files', (done) => {
31+
const req = request(app).post('/upload/multiple');
32+
33+
['car.png', 'tree.png', 'basketball.png', 'car.png'].forEach((fileName, index) => {
34+
let filePath = path.join(fileDir, fileName);
35+
req.attach(`testFile${index+1}`, filePath);
36+
});
37+
38+
req
39+
.expect(500, {response: 'Too many files!'})
40+
.end(() => {
41+
assert.ok(numFilesLimitHandlerRun, 'handler was run');
42+
done();
43+
});
44+
});
45+
46+
it('Does not run handler when number of files is below limit', (done) => {
47+
const req = request(app).post('/upload/multiple');
48+
49+
['car.png', 'tree.png', 'basketball.png'].forEach((fileName, index) => {
50+
let filePath = path.join(fileDir, fileName);
51+
req.attach(`testFile${index+1}`, filePath);
52+
});
53+
54+
req
55+
.expect(200)
56+
.end(() => {
57+
assert.ok(!numFilesLimitHandlerRun, 'handler was not run');
58+
done();
59+
});
60+
});
61+
});
62+
});

0 commit comments

Comments
 (0)