2013-09-30 43 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會話來完成。 –