Node.jsstream直接上传到Google云端存储

我有一个运行在Google Compute VM实例上的Node.js应用程序,它直接从POST请求(不通过浏览器)接收file upload,并将传入的数据stream式传输到Google Cloud Storage(GCS)。

我正在使用Restify b / c我不需要Express的额外function,因为它可以很容易地stream入传入的数据。

我为这个文件创build一个随机的文件名,把传入的req转移到一个整洁的小节点封装器(可以在这里find: https : //github.com/bsphere/node-gcs ),它向GCS发出一个PUT请求。 使用PUT的GCS文档可以在这里find: https : //developers.google.com/storage/docs/reference-methods#putobject …它说如果使用chunked transfer encoding Content-Length是不必要的。

好消息:该文件正在相应的GCS存储“桶”内创build!

坏消息:

  1. 我还没有想出如何从Restify获取传入文件的扩展名(注意手动设置'.jpg' content-type )。

  2. 该文件正在经历轻微的腐败(几乎可以肯定地做我做错了PUT请求)。 如果我从Google下载POST文件,OSX告诉我它的损坏…但是,如果我使用PhotoShop,它打开,看起来很好。

更新/解决scheme

正如vkurchatkin所指出的vkurchatkin ,我需要parsingrequest对象,而不是仅仅把所有东西都传送给GCS。 在尝试了更轻的busboy模块之后,我决定使用multiparty更容易一些。 为了dynamic设置Content-Type ,我简单地使用Mimer ( https://github.com/heldr/mimer ),引用传入文件的文件扩展名。 重要的是要注意,由于我们正在pipe道part对象, part头必须被清除。 否则,意想不到的信息,特别是content-type将被传递,并且可能会与我们试图明确设置的content-type冲突。

以下是适用的修改后的代码:

 var restify = require('restify'), server = restify.createServer(), GAPI = require('node-gcs').gapitoken, GCS = require('node-gcs'), multiparty = require('multiparty'), Mimer = require('mimer'); server.post('/upload', function(req, res) { var form = new multiparty.Form(); form.on('part', function(part){ var fileType = '.' + part.filename.split('.').pop().toLowerCase(); var fileName = Math.random().toString(36).slice(2) + fileType; // clear out the part's headers to prevent conflicting data being passed to GCS part.headers = null; var gapi = new GAPI({ iss: '-- your -- @developer.gserviceaccount.com', scope: 'https://www.googleapis.com/auth/devstorage.full_control', keyFile: './key.pem' }, function(err) { if (err) { console.log('google cloud authorization error: ' + err); } var headers = { 'Content-Type': Mimer(fileType), 'Transfer-Encoding': 'Chunked', 'x-goog-acl': 'public-read' }; var gcs = new GCS(gapi); gcs.putStream(part, myBucket, '/' + fileName, headers, function(gerr, gres){ console.log('file should be there!'); }); }); }); }; 

你不能使用原始reqstream,因为它产生了整个请求体,这是multipart。 你需要用像multiparty这样的东西parsing请求给你一个可读的蒸汽和你需要的所有元数据。