File.resume() docx file busboy finish event
See original GitHub issueHello!
In order to discard not allowed extensions I use file.resume() to get off not allowed files and let start with another or finish the form upload.
All went smooth until some type of .docx knock my door.
The problem is when we upload this type of file, Busboy never gets finish signal and browser connection hangs until time out, with other not allowed files they get rejected, Busboy knows when the upload finished.
$> node -v
v10.15.0
Busboy version:
"busboy": "^0.3.0",
To reproduce this behaviour:
$> curl https://transfer.sh/K1mPC/f2.docx -o f2.docx
$> file -bi 'f2.docx'
application/zip; charset=binary
$> node server.bug.js
$> curl -i -X POST -H "Content-Type: multipart/form-data" -F "data=@f2.docx" http://localhost:3000/busboy
HTTP/1.1 100 Continue
curl: (56) Recv failure: Connection reinitialized by the remote machine
-Server Output:
readFirstBytes...
File [data]: filename: f2.docx, encoding: 7bit, mimetype: application/octet-stream
readFirstBytes...
Rejected file of type docx
File ON ERROR [f2.docx] ERROR -> EXT NOT ALLOWED
File ON END [f2.docx] Finished
Reached the end, but did not read anything.
I can upload other doc or docx files and they get rejected and busboy.on(‘finish’) gets executed:
$> curl https://transfer.sh/pyFD3/f1.docx -o f1.docx
$> file -bi 'f1.docx'
application/octet-stream; charset=binary
$> curl -i -X POST -H "Content-Type: multipart/form-data" -F "data=@f1.docx" http://localhost:3000/busboy
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Date: Tue, 22 Jan 2019 07:35:28 GMT
Connection: keep-alive
Content-Length: 18
Done parsing form!
-Server Output:
readFirstBytes...
File [data]: filename: f1.docx, encoding: 7bit, mimetype: application/octet-stream
readFirstBytes...
Rejected file of type docx
File ON ERROR [f1.docx] ERROR -> EXT NOT ALLOWED
File ON END [f1.docx] Finished
Reached the end, but did not read anything.
Done parsing form!
server.js
const http = require('http');
const fs = require('fs');
const path = require('path');
const Busboy = require('busboy');
const fileType = require('file-type');
const port = 3000;
const host = "localhost";
/**
* Create Server
*/
const server = http.createServer((req, res) => {
const url = req.url;
if (url === '/') {
return renderForm(res);
} else if (url === '/busboy' && req.method === 'POST') {
return uploadFiles(req, res);
} else {
return notFound(res);
}
})
server.listen(port, host, () => {
console.log(`Server running at http://${host}:${port}/`);
});
/**
* Upload Files
*
* @param {*} req
* @param {*} res
*/
const uploadFiles = (req, res) => {
const opt = {
dest: path.join(__dirname, '.'),
limits: {
fileSize: 1024 * 1024,
files: 2
}
};
var busboy = new Busboy({
headers: req.headers,
opt: opt
});
busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
function readFirstBytes() {
console.log("readFirstBytes...")
var chunk = file.read(fileType.minimumBytes);
if (!chunk) return file.once('readable', readFirstBytes);
const type = fileType(chunk);
let ext = "foo";
if (type) ext = type.ext
file.unshift(chunk);
if (ext === 'jpeg' || ext === 'jpg' || ext === 'png') {
console.log("checkExtention allow ---> ", ext)
file.pipe(fs.createWriteStream('./' + filename));
} else {
console.log('Rejected file of type ' + ext);
file.resume().on('end', () => {
console.log('Reached the end, but did not read anything.');
}); // Drain file stream to continue processing form
file.emit('error', 'EXT NOT ALLOWED')
file.emit('close')
file.emit('end')
}
}
readFirstBytes();
console.log('File [' + fieldname + ']: filename: ' + filename + ', encoding: ' + encoding + ', mimetype: ' + mimetype);
file.on('error', function (e) {
console.log('File ON ERROR [' + filename + '] ERROR -> ', e);
}).on('end', function () {
console.log('File ON END [' + filename + '] Finished');
}).on('limit', () => {
console.log(`bytes limit ${opt.limits.fileSize} exceeded on File: ${filename}`);
file.resume(); //fires finish
});
}).on('filesLimit', () => {
console.log('MAX FILES REACHED, LIMIT IS: ', opt.limits.files)
}).on('finish', (f) => {
console.log('Done parsing form!');
return res.end('Done parsing form!');
});
req.pipe(busboy);
}
/**
* Not Found Res
*
* @param {*} res
*/
const notFound = (res) => {
res.statusCode = 404;
res.setHeader('Content-Type', 'text/html');
res.end('<h1>404 NOT FOUND</h1>');
}
/**
* Render Upload Form
*
* @param {*} res
*/
const renderForm = (res) => {
res.write('<h1>Upload Files<h1>');
res.end(
'<form action="/busboy" enctype="multipart/form-data" method="post">' +
'<input type="text" name="title"><br>' +
'<input type="file" name="upload" multiple="multiple"><br>' +
'<input type="submit" value="Upload">' +
'</form>'
);
}
Thanks for reading.
Issue Analytics
- State:
- Created 5 years ago
- Comments:5 (3 by maintainers)
Top Results From Across the Web
busboy not firing finish event - Stack Overflow
You need to consume the file stream somehow. For testing purposes you can ignore the data by adding file.resume(); inside the file event...
Read more >busboy, upload few files, 'finish' event doesn't work properly
Hello,. I trying to upload few files through one input[type=file] with attribue 'multiple'. All work fine but 'finish' event firing ...
Read more >Resumable Multi-File Uploader using XMLHttpRequest ...
A detailed walkthrough on how to create a resumable multi- file uploader, ... Uploader using XMLHttpRequest, NodeJs Express and Busboy.
Read more >How to Create a Resumable MultiFile Uploader with NodeJs
For this project, I'll show you how to build a file uploader that handles multiple files at once with the ability to pause...
Read more >File uploads using Node.js - CodeForGeek
In HTML form you must mention enctype=”multipart/form-data” else multer will not work. Performing file validation: To perform validation on Server end, multer ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Alright as noted in the upstream issue, this should’ve been fixed in node v10.15.1.
Upstream bug report: https://github.com/nodejs/node/issues/25642