Download Progress - Request
I upload 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 downloaded? Is there some kind of event that I can subscribe to, or is there a Request property that I can poll?
If not, what is the best way to download data and find out how much was downloaded?
I need a handle to complete the download for another project of mine.
I found out that you can poll the request 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 go to r , instead of polling r.req.connection.socket._bytesDispatched .
I spent a couple of hours to find something right in the request and node sources, and finally found another approach that seems more correct to me.
We can rely on the drain event and the bytesWritten property:
request.put({ url: 'https://example.org/api/upload', body: fs.createReadStream(path) }).on('drain', () => { console.log(req.req.connection.bytesWritten); }); Alternatively, if you need to handle the progress of file bytes, it is easier to use the data stream event:
let size = fs.lstatSync(path).size; let bytes = 0; request.put({ url: 'https://example.org/api/upload', body: fs.createReadStream(path).on('data', (chunk) => { console.log(bytes += chunk.length, size); }) }); The stream buffer is 65536 bytes in size and the read / leak procedure is iterative.
This seems to work pretty well for me with node v4.5.0 and request v2.74.0 .
var request = require('request'); var fs = require('fs'); let path ="C:/path/to/file"; var formData = { vyapardb: fs.createReadStream(path) }; let size = fs.lstatSync(path).size; var headers = { 'Accept' : 'application/json', 'Authorization' : 'Bearer '+token, }; var r = request.post({url:'http://35.12.13/file/upload', formData: formData, headers: headers}, function optionalCallback(err, httpResponse, body) { clearInterval(q); }); var q = setInterval(function () { var dispatched = r.req.connection._bytesDispatched; let percent = dispatched*100/size; console.dir("Uploaded: " + percent + "%"); }, 250); } I know this is old, but I just found the 'progress-stream' library that has not been mentioned and does it very well. https://www.npmjs.com/package/progress-stream
const streamProg = require('progress-stream'); const fs = require('fs'); const request = require('request'); const myFile = 'path/to/file.txt'; const fileSize = fs.statSync('path/to/file.txt').size; const readStream = fs.createReadStream(myFile); const progress = streamProg({time: 1000, length: fileSize}) .on('progress', state => console.log(state)); readStream.pipe(progress).pipe(request.put({url: 'SOMEURL/file.txt'})); Similarly, this can be used between channel loading.
Someone created a good module to accomplish this, which was run on the production stack for transloadit (so that it is reliable and well supported). You can find it here:
https://github.com/felixge/node-formidable
The code should look like this:
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); Then you can push the status to the client using Socket.io
Interesting note. This was one of the problems that led to the creation of Node. In this video, Ryan talks about the beginning of Node, trying to find the best way to notify the user, download the status of the file in real time via the Internet ... anyway, Iām distracted, but the video is worth a look if you are interested in the Node story
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"); });