Socket
Socket
Sign inDemoInstall

express-fileupload

Package Overview
Dependencies
13
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.0 to 1.1.1-alpha.1

.prettierrc

1

example/README.md

@@ -16,2 +16,3 @@ # express-fileupload Examples

return res.status(400).send('No files were uploaded.');
}

@@ -18,0 +19,0 @@ // The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file

7

example/server.js
const express = require('express');
const fileUpload = require('../lib/index.js');
const fileUpload = require('../lib/index');
const app = express();
const PORT = 8000;
app.use('/form', express.static(__dirname + '/index.html'));

@@ -38,4 +39,4 @@

app.listen(8000, function() {
console.log('Express server listening on port 8000'); // eslint-disable-line
app.listen(PORT, function() {
console.log('Express server listening on port ', PORT); // eslint-disable-line
});

@@ -9,6 +9,7 @@ 'use strict';

module.exports = function(options, fileUploadOptions = null) {
return {
const output = {
name: options.name,
data: options.buffer,
encoding: options.encoding,
tempFilePath: options.tempFilePath,
truncated: options.truncated,

@@ -20,18 +21,42 @@ mimetype: options.mimetype,

if (callback) {
doMove(
() => {
callback(null);
},
(error) => {
callback(error);
}
);
if (options.buffer.length && !options.tempFilePath) {
moveFromBuffer(
() => {
callback(null);
},
error => {
callback(error);
}
);
} else {
moveFromTemp(
() => {
callback(null);
},
error => {
callback(error);
}
);
}
// Otherwise, return a promise
// Otherwise, return a promise
} else {
return new Promise((resolve, reject) => {
doMove(resolve, reject);
if (options.buffer) {
moveFromBuffer(resolve, reject);
} else {
moveFromTemp(resolve, reject);
}
});
}
function checkAndMakeDir(){
if (fileUploadOptions && fileUploadOptions.createParentPath) {
const parentPath = path.dirname(filePath);
if (!fs.existsSync(parentPath)) {
fs.mkdirSync(parentPath);
}
}
}
/**

@@ -43,10 +68,16 @@ * Local function that moves the file to a different location on the filesystem

*/
function doMove(successFunc, errorFunc) {
if (fileUploadOptions && fileUploadOptions.createParentPath) {
const parentPath = path.dirname(filePath);
if (!fs.existsSync(parentPath)) {
fs.mkdirSync(parentPath);
function moveFromTemp(successFunc, errorFunc) {
checkAndMakeDir();
fs.rename(options.tempFilePath, filePath, function(err){
if (err) {
errorFunc(err);
} else {
successFunc();
}
}
});
}
function moveFromBuffer(successFunc, errorFunc) {
checkAndMakeDir();
const fstream = fs.createWriteStream(filePath);

@@ -66,2 +97,8 @@

};
if (options.size) {
output.size = options.size;
}
return output;
};

@@ -6,2 +6,3 @@ 'use strict';

const isEligibleRequest = require('./isEligibleRequest');
const processNested = require('./processNested');

@@ -12,3 +13,6 @@ const fileUploadOptionsDefaults = {

abortOnLimit: false,
createParentPath: false
createParentPath: false,
parseNested: false,
useTempFiles: false,
tempFileDir: '/tmp'
};

@@ -32,4 +36,5 @@

/**
* Quietly expose fileFactory; useful for testing
* Quietly expose fileFactory and processNested; useful for testing
*/
module.exports.fileFactory = fileFactory;
module.exports.processNested = processNested;
const Busboy = require('busboy');
const fileFactory = require('./fileFactory');
const {
getTempFilePath,
complete,
cleanupStream,
tempFileHandler
} = require('./tempFileHandler');
const processNested = require('./processNested');

@@ -40,3 +47,3 @@ /**

if (!prev) {
return req.body[fieldname] = val;
return (req.body[fieldname] = val);
}

@@ -55,6 +62,15 @@

let safeFileNameRegex = /[^\w-]/g;
const memHandler = function(data) {
buffers.push(data);
if (options.debug) {
return console.log('Uploading %s -> %s', fieldname, filename); // eslint-disable-line
}
};
const dataHandler = options.useTempFiles
? tempFileHandler(options, fieldname, filename)
: memHandler;
file.on('limit', () => {
if (options.abortOnLimit) {
res.writeHead(413, {'Connection': 'close'});
res.writeHead(413, { Connection: 'close' });
res.end('File size limit has been reached');

@@ -64,10 +80,4 @@ }

file.on('data', function(data) {
buffers.push(data);
file.on('data', dataHandler);
if (options.debug) {
return console.log('Uploading %s -> %s', fieldname, filename); // eslint-disable-line
}
});
file.on('end', function() {

@@ -77,8 +87,11 @@ if (!req.files) {

}
if (options.useTempFiles) {
complete(filename);
}
const buf = Buffer.concat(buffers);
const buffer = Buffer.concat(buffers);
// see: https://github.com/richardgirges/express-fileupload/issues/14
// firefox uploads empty file in case of cache miss when f5ing page.
// resulting in unexpected behavior. if there is no file data, the file is invalid.
if (!buf.length) {
if (!buffer.length && !options.useTempFiles) {
return;

@@ -108,9 +121,15 @@ }

if (extension.length > maxExtensionLength && maxExtensionLength > 0) {
if (
extension.length > maxExtensionLength &&
maxExtensionLength > 0
) {
filenameParts[filenameParts.length - 1] +=
'.' + extension.substr(0, extension.length - maxExtensionLength);
'.' +
extension.substr(0, extension.length - maxExtensionLength);
extension = extension.substr(-maxExtensionLength);
}
extension = maxExtensionLength ? '.' + extension.replace(safeFileNameRegex, '') : '';
extension = maxExtensionLength
? '.' + extension.replace(safeFileNameRegex, '')
: '';
filename = filenameParts.join('.');

@@ -123,9 +142,13 @@ }

const newFile = fileFactory({
name: filename,
buffer: buf,
encoding: encoding,
truncated: file.truncated,
mimetype: mime
}, options);
const newFile = fileFactory(
{
name: filename,
buffer,
tempFilePath: getTempFilePath(),
encoding,
truncated: file.truncated,
mimetype: mime
},
options
);

@@ -145,6 +168,12 @@ // Non-array fields

file.on('error', next);
file.on('error', cleanupStream, next);
});
busboy.on('finish', next);
busboy.on('finish', () => {
if (options.parseNested) {
req.body = processNested(req.body);
req.files = processNested(req.files);
}
next();
});

@@ -154,2 +183,2 @@ busboy.on('error', next);

req.pipe(busboy);
};
};
{
"name": "express-fileupload",
"version": "1.0.0",
"version": "1.1.1-alpha.1",
"author": "Richard Girges <richardgirges@gmail.com>",

@@ -35,3 +35,3 @@ "description": "Simple express file upload middleware that wraps around Busboy",

"coveralls": "^3.0.2",
"eslint": "^5.6.0",
"eslint": "^5.9.0",
"express": "^4.16.3",

@@ -38,0 +38,0 @@ "istanbul": "^0.4.5",

@@ -56,2 +56,12 @@ # express-fileupload

### Using useTempFile Options
Use temp files instead of memory for managing the upload process.
Please note: md5 hashes will not be generated when using tempFiles
```javascript
app.use(fileUpload({
useTempFiles : true,
tempFileDir : '/tmp/'
}));
```
### Available Options

@@ -66,7 +76,10 @@ Pass in non-Busboy options directly to the middleware. These are express-fileupload specific options.

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>truncate = true</code> to the resulting file structure.
useTempFiles | <ul><li><code>false</code>&nbsp;**(default)**</li><li><code>true</code></ul> | Will use temporary files at the specified tempDir for managing uploads rather than using buffers in memory. This avoids memory issues when uploading large files.
tempFileDir | <ul><li><code>String</code>&nbsp;**(path)**</li></ul> | Used with the <code>useTempFiles</code> option. Path to the directory where temp files will be stored during the upload process. Add trailing slash.
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>
# Help Wanted
Pull Requests are welcomed!
Looking for additional maintainers. Please contact `richardgirges [ at ] gmail.com` if you're interested. Pull Requests are welcomed!
# Thanks & Credit
[Brian White](https://github.com/mscdex) for his stellar work on the [Busboy Package](https://github.com/mscdex/busboy) and the [connect-busboy Package](https://github.com/mscdex/connect-busboy)

@@ -188,2 +188,33 @@ const fs = require('fs');

});
describe('Testing [parseNested] option to ensure:', function() {
it('When [parseNested] is enabled result are nested', function(done){
const app = server.setup({parseNested: true});
request(app)
.post('/fields/nested')
.field('name', 'John')
.field('hobbies[0]', 'Cinema')
.field('hobbies[1]', 'Bike')
.expect('Content-Type', /json/)
.expect(200, {
name: 'John',
hobbies: ['Cinema', 'Bike']
}, done);
});
it('When [parseNested] is disabled are flattened', function(done){
const app = server.setup({parseNested: false});
request(app)
.post('/fields/flattened')
.field('name', 'John')
.field('hobbies[0]', 'Cinema')
.field('hobbies[1]', 'Bike')
.expect('Content-Type', /json/)
.expect(200, {
name: 'John',
'hobbies[0]': 'Cinema',
'hobbies[1]': 'Bike'
}, done);
});
});
});

@@ -53,7 +53,8 @@ 'use strict';

testFile.mv(uploadPath)
testFile
.mv(uploadPath)
.then(() => {
res.send('File uploaded to ' + uploadPath);
})
.catch((err) => {
.catch(err => {
res.status(500).send(err);

@@ -217,2 +218,45 @@ });

app.all('/fields/nested', function(req, res) {
if (!req.body) {
return res.status(400).send('No request body found');
}
if (!req.body.name || !req.body.name.trim()) {
return res.status(400).send('Invalid name');
}
if (!req.body.hobbies || !req.body.hobbies.length == 2) {
return res.status(400).send('Invalid hobbies');
}
res.json({
name: req.body.name,
hobbies: req.body.hobbies
});
});
app.all('/fields/flattened', function(req, res) {
if (!req.body) {
return res.status(400).send('No request body found');
}
if (!req.body.name || !req.body.name.trim()) {
return res.status(400).send('Invalid name');
}
if (!req.body['hobbies[0]'] || !req.body['hobbies[0]'].trim()) {
return res.status(400).send('Invalid hobbies[0]');
}
if (!req.body['hobbies[1]'] || !req.body['hobbies[1]'].trim()) {
return res.status(400).send('Invalid hobbies[1]');
}
res.json({
name: req.body.name,
'hobbies[0]': req.body['hobbies[0]'],
'hobbies[1]': req.body['hobbies[1]']
});
});
app.all('/fields/array', function(req, res) {

@@ -219,0 +263,0 @@ if (!req.body) {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc