express/connect-form form event listeners not firing
Problem
I've recently upgraded my environment to Node v0.6.3 and some file upload functionality that was working fine before has stopped working. I am posting a file upload form to the following page:
var fs = require('fs'),
client = require('../app'),
exec = require('child_process').exec,
socket = require('../socket')
var supported = [ 'image/jpeg',
'image/pjpeg',
'image/bmp',
'image/gif',
'image/tiff',
'image/png']
var maxSize = 204800;
module.exports = function(req, res) {
console.log(JSON.stringify(req.form));
var tmpPath = '';
req.form.on('fileBegin', function(err, fileInfo) {
console.log('upload file begin')
if (fileInfo.path) {tmpPath = fileInfo.path};
socket.emit('attachment_upload_started', req.query.user, {friend: req.query.friend}, []);
});
req.form.on('progress', function(bytesReceived, bytesExpected) {
var percent = (bytesReceived / bytesExpected * 100) | 0;
socket.emit('attachment_progress', req.query.user, {progress: percent, friend: req.query.friend}, []);
var child = exec('file --mime-type ' + tmpPath, function (err, stdout, stderr) {
var mimetype = stdout.substring(stdout.lastIndexOf(':') + 2, stdout.lastIndexOf('\n'));
if (!err && mimetype && supported.indexOf(mimetype)==-1 && mimetype!='Can\'t read SAT') {
socket.emit('attachment_error', req.query.user, {type: 'format', friend: req.query.friend}, []);
req.connection.destroy();
req.connection.resume = function(){};
console.log(mimetype)
console.log(err);
}
if (bytesExpected > maxSize) {
socket.emit('attachment_error', req.query.user, {type: 'size', friend: req.query.friend}, []);
req.connection.destroy();
req.connection.resume = function(){}
}
});
});
req.form.complete(function(err, fields, files){
console.log('form complete');
if (!err) {
if (supported.indexOf(files.upload.mime)==-1) {
console.log(files.upload.mime);
socket.emit('attachment_error', req.query.user, {type: 'format', friend: req.query.friend}, []);
}
else {
socket.emit('attachment_complete', req.query.user, {friend: req.query.friend, file: files.upload}, []);
}
}
else {
console.log('err');
}
res.redirect('/iattachment?user='+req.query.user+'&friend='+req.query.friend);
});
}
The file does indeed make it to my /tmp directory, but none of the code within the req.form.complete, or req.form.on('progress'), req.form.on('fileBegin') listeners gets executed. Any help would be appreciated!
Solution
Are you using express.bodyParser?
The problem is that connect, the module that express is based on, now includes formidable as of version 2.0, but nobody bothered to change the documentation or examples. (Actually, let me do that right now.)
If you are already using the bodyParser, the temporary file is already created, and since the request is already processed and the stream is all read, your code is not really doing anything, and waiting for input.
Check on "req.body" and it should contain all the files information. Otherwise try removing express.bodyParser.
Discussion
View additional discussion.