问题
I'm using busboy, writing my uploaded file to a buffer and performing some validation on it (width, height and filesize). I can't for the life of me figure out how to abort / stop the stream once I find something wrong with the upload.
For instance if I have a max filesize of 500kb that I want to allow, I keep track of the size of the buffer as it's uploading and I want to abort if the size is over 500kb.
Here's a simplified version of my code.
var self = this;
var busboy = new Busboy({
headers: self.req.headers,
limits: {
files: 1
}
});
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
file.fileRead = [];
var size = 0;
file.on('data', function(chunk) {
size += chunk.length;
/* DO VALIDATION HERE */
if( size > 500000) {
/*** ABORT HERE ***/
}
file.fileRead.push(chunk);
});
file.on('end', function() {
var data = Buffer.concat(file.fileRead, size);
// ... upload to S3
});
self.req.pipe(busboy);
});
回答1:
Ok, so I had the same problem and I solved it with file.resume();
var fstream;
req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
// Validate file mimetype
if(mimetype != 'image/png'){
file.resume();
return res.json({
success: false,
message: 'Invalid file format'
});
}
// Upload
fstream = fs.createWriteStream(__dirname + '/tmp/' + timestamp + filename);
file.pipe(fstream);
fstream.on('close', function () {
return res.json({
success: true
});
});
});
req.pipe(req.busboy);
回答2:
I would try something like this:
var self = this;
var busboy = new Busboy({
headers: self.req.headers,
limits: {
files: 1,
fileSize: 500000
}
});
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
file.fileRead = [];
file.on('limit', function() {
//Clear variables
});
file.on('data', function(chunk) {
file.fileRead.push(chunk);
});
file.on('end', function() {
var data = Buffer.concat(file.fileRead, size);
// ... upload to S3
});
self.req.pipe(busboy);
});
Basically I added a new limit in the configuration of Busboy: fileSize: 500 * 1024
And I started listening limit event:
file.on('limit', function() {
//Clear vars
});
回答3:
The answer is simple one.
// do the required validation like size check etc.
if( size > 500000)
{
self.req.unpipe();
return;
}
The context is this. I see in busboy code that busboy is implemented as WritableStream and underneath uses Dicer
module for parsing which is also implemented as WritableStream. Flow is like this:
req
stream ==> busboy ==> dicer ==> dicer raises events ==> busboy raises events on file ==> these events are consumed in your code.
To stop this whole flow of code - the above unpipe should do.
回答4:
I would think the proper thing to do was to just close the socket and end the request
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
file.fileRead = [];
var size = 0;
file.on('data', function(chunk) {
size += chunk.length;
/* DO VALIDATION HERE */
if( size > 500000) {
self.req.socket.end();
self.res.end();
}
file.fileRead.push(chunk);
});
file.on('end', function() {
var data = Buffer.concat(file.fileRead, size);
// ... upload to S3
});
self.req.pipe(busboy);
});
回答5:
I was able to access the underlying Dicer
parser which has an ignore
method which essentially stops uploading the file.
Here's how I did it: busboy._parser.parser._ignore()
It does seem very hackish, but it works and does exactly what I wanted.
来源:https://stackoverflow.com/questions/30465882/node-busboy-abort-upload