I'm uploading a file using Request
.
req = request.post url: "http://foo.com", body: fileAsBuffer, (err, res, body) ->
console.log "Uploaded!"
How do I know how much data has actually been uploaded? Is there some event that I can subscribe to or is there a property of the request
that I can poll?
If none, what would be the best approach to upload data and know how much has been uploaded?
I needed a handle on the upload progress for yet another project of mine.
What I found out is that you can poll the request
's connection._bytesDispatched
property.
For example:
r = request.post url: "http://foo.com", body: fileAsBuffer
setInterval (-> console.log "Uploaded: #{r.req.connection._bytesDispatched}"), 250
Note: If you were piping to r
, poll r.req.connection.socket._bytesDispatched
instead.
Someone has created a nice module to accomplish this that has been running in the production stack for transloadit (so it is dependable and well maintained). You can find it here:
https://github.com/felixge/node-formidable
Code should look like:
var formidable = require('formidable'),
http = require('http'),
util = require('util');
http.createServer(function(req, res) {
if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
// parse a file upload
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received upload:\n\n');
res.end(util.inspect({fields: fields, files: files}));
});
return;
}
// show a file upload form
res.writeHead(200, {'content-type': 'text/html'});
res.end(
'<form action="/upload" 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>'
);
}).listen(80);
You could then push status to a client using Socket.io
Interesting Note: This was one of the problems that led to Node's creation. In this video Ryan talks about how node was started trying to find the best way of notifying a user, real time, about the status of file upload over the web...anyway I digress, but the video is worth a watch if you are interested in Node's history
Try this approach:
var file = fs.createWriteStream("largefile.jpg");
var totalbytes = request.headers['content-length'];
var donesofar = 0;
request.pipe(file);
request.on('data', function(chunk){
donesofar += chunk.length;
var progress = (donesofar / totalbytes) * 100;
response.write(parseInt(progress, 10) + "%\n");
});