express-fileupload
Advanced tools
Comparing version 1.1.7-alpha.3 to 1.1.7-alpha.4
@@ -42,3 +42,3 @@ 'use strict'; | ||
// resulting in unexpected behavior. if there is no file data, the file is invalid. | ||
if (!fileUploadOptions.useTempFiles && !options.buffer.length) return; | ||
// if (!fileUploadOptions.useTempFiles && !options.buffer.length) return; | ||
@@ -45,0 +45,0 @@ // Create and return file object. |
@@ -62,2 +62,4 @@ const Busboy = require('busboy'); | ||
const uploadTimer = new UploadTimer(options.uploadTimeout, () => { | ||
file.removeAllListeners('data'); | ||
file.resume(); | ||
// After destroy an error event will be emitted and file clean up will be done. | ||
@@ -92,5 +94,8 @@ file.destroy(new Error(`Upload timeout ${field}->${filename}, bytes:${getFileSize()}`)); | ||
uploadTimer.clear(); | ||
// See https://github.com/richardgirges/express-fileupload/issues/191 | ||
// Do not add file instance to the req.files if original name and size are empty. | ||
// Empty name and zero size indicates empty file field in the posted form. | ||
if (!name && size === 0) return; | ||
if (!name && size === 0) { | ||
return debugLog(options, `Don't add file instance if original name and size are empty`); | ||
} | ||
req.files = buildFields(req.files, field, fileFactory({ | ||
@@ -127,2 +132,3 @@ buffer: complete(), | ||
busboy.on('finish', () => { | ||
debugLog(options, `Busboy finished parsing request.`); | ||
if (options.parseNested) { | ||
@@ -145,5 +151,8 @@ req.body = processNested(req.body); | ||
busboy.on('error', next); | ||
busboy.on('error', (err) => { | ||
debugLog(options, `Busboy error`); | ||
next(err); | ||
}); | ||
req.pipe(busboy); | ||
}; |
@@ -21,19 +21,12 @@ const fs = require('fs'); | ||
let completed = false; | ||
let writeStream = false; | ||
let writePromise = Promise.resolve(); | ||
const createWriteStream = () => { | ||
debugLog(options, `Opening write stream for ${fieldname}->${filename}...`); | ||
writeStream = fs.createWriteStream(tempFilePath); | ||
writePromise = new Promise((resolve, reject) => { | ||
writeStream.on('finish', () => { | ||
resolve(); | ||
}); | ||
writeStream.on('error', (err) => { | ||
debugLog(options, `Error write temp file: ${err}`); | ||
reject(err); | ||
}); | ||
debugLog(options, `Opening write stream for ${fieldname}->${filename}...`); | ||
const writeStream = fs.createWriteStream(tempFilePath); | ||
const writePromise = new Promise((resolve, reject) => { | ||
writeStream.on('finish', () => resolve()); | ||
writeStream.on('error', (err) => { | ||
debugLog(options, `Error write temp file: ${err}`); | ||
reject(err); | ||
}); | ||
}; | ||
}); | ||
@@ -46,3 +39,2 @@ return { | ||
} | ||
if (writeStream === false) createWriteStream(); | ||
writeStream.write(data); | ||
@@ -65,10 +57,8 @@ hash.update(data); | ||
completed = true; | ||
if (writeStream !== false) { | ||
debugLog(options, `Cleaning up temporary file ${tempFilePath}...`); | ||
writeStream.end(); | ||
deleteFile(tempFilePath, err => (err | ||
? debugLog(options, `Cleaning up temporary file ${tempFilePath} failed: ${err}`) | ||
: debugLog(options, `Cleaning up temporary file ${tempFilePath} done.`) | ||
)); | ||
} | ||
debugLog(options, `Cleaning up temporary file ${tempFilePath}...`); | ||
writeStream.end(); | ||
deleteFile(tempFilePath, err => (err | ||
? debugLog(options, `Cleaning up temporary file ${tempFilePath} failed: ${err}`) | ||
: debugLog(options, `Cleaning up temporary file ${tempFilePath} done.`) | ||
)); | ||
}, | ||
@@ -75,0 +65,0 @@ getWritePromise: () => writePromise |
@@ -5,3 +5,3 @@ 'use strict'; | ||
const path = require('path'); | ||
const Readable = require('stream').Readable; | ||
const { Readable } = require('stream'); | ||
@@ -31,13 +31,13 @@ // Parameters for safe file name parsing. | ||
/** | ||
* Generates unique temporary file name like: tmp-5000-156788789789. | ||
* Generates unique temporary file name. e.g. tmp-5000-156788789789. | ||
* @param {string} prefix - a prefix for generated unique file name. | ||
* @returns {string} | ||
*/ | ||
const getTempFilename = (prefix) => { | ||
const getTempFilename = (prefix = TEMP_PREFIX) => { | ||
tempCounter = tempCounter >= TEMP_COUNTER_MAX ? 1 : tempCounter + 1; | ||
return `${prefix || TEMP_PREFIX}-${tempCounter}-${Date.now()}`; | ||
return `${prefix}-${tempCounter}-${Date.now()}`; | ||
}; | ||
/** | ||
* isFunc- check if argument is a function. | ||
* isFunc: Checks if argument is a function. | ||
* @returns {boolean} - Returns true if argument is a function. | ||
@@ -65,3 +65,3 @@ */ | ||
*/ | ||
const buildOptions = function(){ | ||
const buildOptions = function() { | ||
const result = {}; | ||
@@ -113,3 +113,3 @@ [...arguments].forEach(options => { | ||
const parentPath = path.dirname(filePath); | ||
// Create folder if it is not exists. | ||
// Create folder if it doesn't exist. | ||
if (!fs.existsSync(parentPath)) fs.mkdirSync(parentPath, { recursive: true }); | ||
@@ -121,6 +121,7 @@ // Checks folder again and return a results. | ||
/** | ||
* Delete file. | ||
* Deletes a file. | ||
* @param {string} file - Path to the file to delete. | ||
* @param {Function} callback | ||
*/ | ||
const deleteFile = (file, callback) => fs.unlink(file, err => err ? callback(err) : callback()); | ||
const deleteFile = (file, callback) => fs.unlink(file, callback); | ||
@@ -155,3 +156,3 @@ /** | ||
/** | ||
* moveFile - moves the file from src to dst. | ||
* moveFile: moves the file from src to dst. | ||
* Firstly trying to rename the file if no luck copying it to dst and then deleteing src. | ||
@@ -162,5 +163,5 @@ * @param {string} src - Path to the source file | ||
*/ | ||
const moveFile = (src, dst, callback) => fs.rename(src, dst, err => (!err | ||
? callback() | ||
: copyFile(src, dst, err => err ? callback(err) : deleteFile(src, callback)) | ||
const moveFile = (src, dst, callback) => fs.rename(src, dst, err => (err | ||
? copyFile(src, dst, err => err ? callback(err) : deleteFile(src, callback)) | ||
: callback() | ||
)); | ||
@@ -186,3 +187,3 @@ | ||
let fstream = fs.createWriteStream(filePath); | ||
fstream.on('error', error => callback(error)); | ||
fstream.on('error', err => callback(err)); | ||
fstream.on('close', () => callback()); | ||
@@ -263,16 +264,16 @@ // Copy file via piping streams. | ||
module.exports = { | ||
isFunc, | ||
debugLog, | ||
isFunc, | ||
copyFile, // For testing purpose. | ||
moveFile, | ||
errorFunc, | ||
deleteFile, // For testing purpose. | ||
buildFields, | ||
buildOptions, | ||
parseFileName, | ||
getTempFilename, | ||
promiseCallback, | ||
buildOptions, | ||
buildFields, | ||
checkAndMakeDir, | ||
deleteFile, // For testing purpose. | ||
copyFile, // For testing purpose. | ||
moveFile, | ||
saveBufferToFile, | ||
parseFileName, | ||
getTempFilename, | ||
uriDecodeFileName | ||
}; |
{ | ||
"name": "express-fileupload", | ||
"version": "1.1.7-alpha.3", | ||
"version": "1.1.7-alpha.4", | ||
"author": "Richard Girges <richardgirges@gmail.com>", | ||
@@ -32,3 +32,3 @@ "description": "Simple express file upload middleware that wraps around Busboy", | ||
"body-parser": "^1.19.0", | ||
"coveralls": "^3.0.11", | ||
"coveralls": "^3.0.14", | ||
"eslint": "^6.8.0", | ||
@@ -38,3 +38,3 @@ "express": "^4.17.1", | ||
"md5": "^2.2.1", | ||
"mocha": "^7.1.1", | ||
"mocha": "^7.2.0", | ||
"rimraf": "^3.0.2", | ||
@@ -41,0 +41,0 @@ "supertest": "^4.0.2" |
@@ -79,3 +79,3 @@ # express-fileupload | ||
It will show you whether the request is invalid and also common events triggered during upload. | ||
That can be really usfull for troubleshhoting and ***we recommend to attach debug output to each issue on Github***. | ||
That can be really useful for troubleshooting and ***we recommend attaching debug output to each issue on Github***. | ||
@@ -116,3 +116,4 @@ ***Output example:*** | ||
parseNested | <ul><li><code>false</code> **(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> | ||
debug | <ul><li><code>false</code> **(default)**</li><li><code>true</code></ul> | Turn on/off upload process logging. Can be usefull for troubleshooting. | ||
debug | <ul><li><code>false</code> **(default)**</li><li><code>true</code></ul> | Turn on/off upload process logging. Can be useful for troubleshooting. | ||
uploadTimeout | <ul><li><code>60000</code> **(default)**</li><li><code>Integer</code></ul> | This defines how long to wait for data before aborting. Set to 0 if you want to turn off timeout checks. | ||
@@ -119,0 +120,0 @@ # Help Wanted |
@@ -29,10 +29,2 @@ 'use strict'; | ||
it('return a file object', () => assert.ok(fileFactory(mockFileOpts))); | ||
it('return void if buffer is empty and useTempFiles is false.', () => { | ||
assert.equal(fileFactory({ | ||
name: mockFileName, | ||
buffer: Buffer.concat([]) | ||
}, { | ||
useTempFiles: false | ||
}), null); | ||
}); | ||
@@ -39,0 +31,0 @@ describe('Properties', function() { |
@@ -15,3 +15,3 @@ 'use strict'; | ||
const mockFiles = ['car.png', 'tree.png', 'basketball.png']; | ||
const mockFiles = ['car.png', 'tree.png', 'basketball.png', 'emptyfile.txt']; | ||
@@ -18,0 +18,0 @@ const mockUser = { |
@@ -43,3 +43,3 @@ 'use strict'; | ||
testFile.mv(fileData.uploadPath, function(err) { | ||
testFile.mv(fileData.uploadPath, (err) => { | ||
if (err) { | ||
@@ -46,0 +46,0 @@ console.log('ERR', err); // eslint-disable-line |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1212132
36
123
2231