2013-09-30 47 views
1

我需要为文件上传中的大文件(.ISO)生成校验和。我使用ExpressJS /连接处理通过POST上传请求(多)如何使用ExpressJS/Connect/Crypto获取(大)文件的校验和?

//express setup app.js 
    app.use('/upload',express.bodyParser({ 
     defer : true, //enable progress event 
     keepExtensions : true, 
     limit : app.locals.fileLimit, 
     uploadDir : path.join(__dirname, '..', 'tmp'), 
     hash : true //this doesnt appear to do anything 
    })); 

    //express route routes.js 
    app.post("/upload", function(req, res){ 

     var fs  = require('fs'); 
     var format = require('util').format; 

     req.form.hash = true; //this doesnt return the hash for some reason 

     req.form.on('fileBegin', function(err) { 
     log.info("Starting new upload..."); 
     }); 

     req.form.on('file', function(name, file) { 
      fs.rename(file.path, req.form.uploadDir + "/" + file.name); 
     console.info(file); 
     }); 

     req.form.on('error', function(err) { 
     log.error('error',err); 
     req.resume(); 
     }); 



     req.form.on('field', function(field, value) { 
     log.info("Passed Field (%s=%s)...",field,value); 
     }); 

     //this part event never gets called for some reason but 
     //I imagine this is where you might do a hash update 
     req.form.on('part', function(part){ 
     console.log('PART upload %s %s', part.name, part.filename); 
     var out = fs.createWriteStream('../tmpstrm/' + part.filename); 
     part.pipe(out); 
     }); 


     req.form.on('progress', function(bytesReceived, bytesExpected) { 
      var percent = (bytesReceived/bytesExpected * 100) | 0; 
      console.info("PROGRESS :"+ ((bytesReceived/bytesExpected)*100) + "% uploaded"); 
     }); 

     req.form.on('end', function() { 
      var fileInfo = format('\nuploaded %s (%d Kb) to %s as %s' 
      , req.files.upload.name 
      , req.files.upload.size/1024 | 0 
      , req.files.upload.path 
      , req.body.title); 

      res.locals.fileInfo = fileInfo; //renders info in jade 

      res.render('media/index'); 
     }); 

    }); 

我找不到我的特殊问题太多信息;这可能不是典型的用例。但一个问题,我确实发现了的how to update the hash on a data event

var hash = crypto.createHash('sha1'); 
var data = // incoming file data 

data.on('data', function(chunk){ 
    hash.update(chunk); 
}); 
data.on('end', function(){ 
    var sha = hash.digest('hex'); 

    // Do something with it 
}) 

一个简单的例子我是新来的流,块等,所以这里的一些指导表示赞赏。

回答

2

有可能会找到有用的在我的一些示例代码编写者消化NPM模块的源代码:

https://github.com/focusaurus/writers-digest/blob/ab52ffca6e989ca657dc449e05ff258c428fa3af/index.js#L38

但基本上有两种方式:

  1. 允许bodyParser到流HTTP请求主体到文件系统,然后通过从文件系统流式传输数据(使用编写者摘要代码作为示例)来计算校验和。

  2. 你可以试着计算校验和,而实际的HTTP请求主体通过结合事件处理函数的req对象dataend事件到达。您应该能够在bodyParser将其流式传输到磁盘时执行此操作。只要确保事件发生的时间足够早,所以你不会错过任何块。

+0

谢谢!你是关于NodeJS问题的经常有用的资源。一些背景信息 - 这是我第一次尝试使其工作,在后续版本中,这应该将写入流重定向到网络上的另一台服务器,因此文件不会存储在机器上运行节点。你有什么想法如何处理?这两种方法仍然适用于此? – qodeninja

+0

因此,您可以将流代理到目标服务器,但请记住这是另一个失败点和不可靠性。我会坚持一个更简单的存储和转发模型,但理论上你可以将文件内容代理到上游服务器上(或者甚至可以配置nginx来为你做)。尽管如此,艰难地将一个体系结构问题作为一个stackoverflow评论来解决。也许可以通过http://airpair.com会话来完成。 –