从节点强大的file upload访问原始文件stream

我正在创build一个应用程序,需要一些file upload,并直接发送到S3。 我宁愿不要在我的服务器上拥有tmp文件,所以我使用的是Knox模块,并希望将来自Formidable的原始数据stream通过Knox发送到S3。 我使用Knox来做类似的事情,使用下面的代码下载一个文件:

knox.downloads.get(widget.download).on('response',function(sres){ res.writeHead(200, { 'Content-Type':'application/zip', 'Content-Length': sres.headers['content-length'], 'Content-Disposition':'attachment; filename=' + widget.download }); util.pump(sres, res); }).end(); 

现在我想在相反的方向做类似的事情(从浏览器上传到S3)。

到目前为止,我已经写了一个事件处理程序来捕获file upload的每一条数据:

 var form = new formidable.IncomingForm(); form.onPart = function(part){ if(!part.filename){ form.handlePart(part); }else{ if(part.name == 'download'){ // Upload to download bucket controller.putDownload(part); }else{ // Upload to the image bucket controller.putImage(part); } //res.send(sys.inspect(part)); } } form.parse(req, function(err, fields, files){ if(err){ res.json(err); }else{ res.send(sys.inspect({fields:fields, files:files}), {'content-type':'text/plain'}); //controller.createWidget(res,fields,files); } }); controller.putDownload = function(part){ part.addListener('data', function(buffer){ knox.download.putStream(data,part.filename, function(err,s3res){ if(err)throwError(err); else{ console.log(s3res); } }); }) knox.downloads.putStream(part, part.filename, function(err,s3res){ if(err)throwError(err); else{ console.log(s3res); } }); } 

但数据事件只给我缓冲区。 那么是否有可能捕获stream本身并推送到S3?

你想要做的是重写Form.onPart方法:

 IncomingForm.prototype.onPart = function(part) { // this method can be overwritten by the user this.handlePart(part); }; 

Formidable的默认行为是将零件写入文件。 你不要那个。 你想处理“部分”事件写入knox下载。 从这开始:

 form.onPart = function(part) { if (!part.filename) { // let formidable handle all non-file parts form.handlePart(part); return; } 

然后打开knox请求并自己处理原始部件事件:

 part.on('data', function(data) { req.write(data); }); part.on('end', function() { req.end(); }); part.on('error', function(err) { // handle this too }); 

作为奖励,如果req.write(data)返回false,这意味着发送缓冲区已满。 你应该暂停Formidableparsing器。 当你从诺克斯stream得到一个drain事件,你应该恢复强大。

改用多方 。 它像你想要的那样支持这种stream式传输。 它甚至有一个直接传输到S3的例子: https : //github.com/superjoe30/node-multiparty/blob/master/examples/s3.js

您无法捕获该stream,因为数据必须由Formidable进行翻译。 你给出的bufferbuffer.length的文件内容:这可能是一个问题,因为查看Formidable的文档,似乎直到文件完全上传,它不能可靠地报告文件的大小和诺克斯的put方法可能需要的。

以前从来没有用过诺克斯,但是你可能有这样的一些运气:

 controller.putDownload = function(part){ var req = knox.download.put(part.filename, { 'Content-Type': 'text/plain' }); part.addListener('data', function(buffer){ req.write(buffer); }); req.on('response', function(res){ // error checking }); req.end(); } 

有一点不确定的答复检查位,但….看看你是否可以鞭打成形。 另外, 在node.js上使用knox将一个八位字节stream从请求stream式传输到S3也有一个可能对您有用的写法。