Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
50
rated 0 times [  56] [ 6]  / answers: 1 / hits: 9177  / 11 Years ago, thu, december 12, 2013, 12:00:00

I have been working on this problem for two days now, and I am stuck. I am using Node.js with Express, and I am trying to implement an upload form. Basically, I want the form to do the following:




  • Check the size of the file and cancel the upload if it is too large (when I say cancel, I mean prevent any further data from being written to disk and remove the temp file)


  • Check the file type and confirm that it is the correct type (.jpg, .png, etc.), if it is not, then stop any further writing to disk and remove the temp file.




Currently, I have the upload working, and I emit errors when a file is too large or it does not match the correct type, and then I remove the file with fs.unlink() after the entire file has been written to disk. But I see a potential problem with this approach: what if a user uploads a huge file (GB's in size)? With my approach right now, it will eventually be removed from my machine but not after wasting a ton of resources. So basically, I am looking to use the minimal amount of resources in order to confirm that a file is okay for uploading. This is the code I have so far:



    var path = absolutePath + '/public/images/users/' + req.session.userId + '/';
var maxSize = 3146000; // 3MB
var form = new formidable.IncomingForm();
form.uploadDir = path;
form.keepExtensions = true;

form.on('error', function(message) {
if(message)
{
res.json({err: message});
}
else
{
res.json({err: 'Upload error, please try again'});
}
});

form.on('fileBegin', function(name, file){
if(form.bytesExpected > maxSize)
{
this.emit('error', 'Size must not be over 3MB');
}
});

form.on('file', function(name, file) {
var type = file.type;
type = type.split('/');
type = type[1];

if(type != 'jpeg' && type != 'png' && type != 'gif')
{
this.emit('error', JPG's, PNG's, GIF's only);
fs.unlink(file.path);
}
else
{
fs.rename(file.path, path + 'profile.' + type);
}
});

form.on('progress', function(bytesReceived, bytesExpected) {
console.log(bytesReceived); //This is just to view progress
});

form.parse(req);


I am also confused because according to the documents at https://github.com/felixge/node-formidable, it says:




A request that experiences an error is automatically paused, you will have to manually call request.resume() if you want the request to continue firing 'data' events.




This would be great, but I can't seem to get it to work. Whenever I emit an 'error', the 'data' events keep firing until completion.



Attempts



I have tried canceling the request when an error is occurred, but to no avail. req.pause() did nothing for me, req.end() and req.abort() gave me an error saying that it wasn't a method, and req.connection.destroy() and req.connection.end() just sent a loop of POST requests.



Final Thoughts



So what I am looking for seems like it should be common-place, but I have spent the last two days searching the internet on a thorough implementation, and I can't seem to find anything. I mean, it is simple to check the size and type of the file AFTER the entire thing has been uploaded, but who wants to waste all of those resources? Not to mention the things that malicious users could do.



I will continue working until I get exactly what I am looking for but I thought that this issue may be relevant for some other users, and hopefully I can get some help!



Thanks for your time.


More From » node.js

 Answers
1

Some time has passed and now you can use multer instead of formidable or multiparty. Multer has desired functionality built in.


[#49580] Thursday, December 12, 2013, 11 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
denzelc

Total Points: 637
Total Questions: 89
Total Answers: 88

Location: Liechtenstein
Member since Wed, Dec 8, 2021
3 Years ago
;