2016-12-23 21 views
1

我試圖從urls列表下載一些文件,但我不想下載任何超過特定大小的文件(比方說1mb)。這些文件可能是千兆字節,所以我需要一種方式在響應流增長到1mb以上時立即取消下載。如何在累積塊的大小大於閾值時結束http響應流

let request = require("request"); 
function getFile(url, callback) { 
    request.get(url) 
    .on('response', function(response) { 
    let output = ""; 
    response.on('data', function(chunk) { 
     if(output.length > 1000000) { 
     // ??? ABORT STREAM HERE ??? 
     console.log(`${url} is too big`); 
     callback(true); 
     } else { 
     output += chunk.toString("utf8"); 
     } 
    }); 
    response.on('end', function() { 
     console.log(`${url} download complete`); 
     callback(null, output); 
    }); 
    }); 
} 

我不知道如何做到這一點。 This github issue for the request library談到中止請求,但我認爲我想中止實際的http響應流而不是請求。一個類似的問題被問到here,但回答者似乎暗示這是不可能的。我確信這是不正確的(或者我錯誤地解釋了他們的答案),否則我將被迫下載我遇到的每個10gig文件。

是否像刪除dataend事件偵聽器一樣簡單?直覺上,我猜測無論是否存在事件,下載都會繼續,但我真的不知道它是如何在幕後工作的。感謝您的任何幫助,您可以提供!

+0

https://www.npmjs.com/package/request-stats – Adiii

+1

http://stackoverflow.com/questions/32295689/how-to-get-byte-size-of-request – Adiii

+1

一旦你得到了大小那麼我認爲你可以輕易取消它 – Adiii

回答

1

我用這個玩了一下,結果發現request包的.abort()方法確實是取消了http響應流。

我一直希望有一種更通用的方式來取消不依賴於請求包的http響應流,但是這會做我的目的,因爲我目前正在使用請求庫。

let request = require("request"); 

function getFile(url, callback) { 
    let tooBig = false; 
    let r = request.get(url) 
    .on('error', callback) 
    .on('response', function(response) { 
     let output = ""; 
     response.on('error', function(error) { 
     callback(error, null); 
     }); 
     response.on('data', function(chunk) { 
     if(output.length > 1000000) { 
      tooBig = true; 
      r.abort(); 
     } else { 
      output += chunk.toString("utf8"); 
     } 
     }); 
     response.on('end', function() { 
     if(tooBig) { 
      console.log(`${url} was too big`); 
      callback("too big", null); 
     } else { 
      console.log(`${url} download complete`); 
      callback(null, output); 
     } 
     }); 
    }); 
} 

另外,如果你使用的要求庫,然後它原來的東西可以簡化多一點:

function getFileSimplified(url, callback) { 
    let output = ""; 
    let tooBig = false; 
    let r = request.get(url) 
    .on('error', callback) 
    .on('data', function(chunk) { 
     if(output.length > 1000000) { 
     tooBig = true; 
     r.abort(); 
     } else { 
     output += chunk.toString("utf8"); 
     } 
    }) 
    .on('end', function() { 
     if(tooBig) { 
     console.log(`${url} was too big`); 
     callback("too big", null); 
     } else { 
     console.log(`${url} download complete`); 
     callback(null, output); 
     } 
    }) 
} 

希望幫助誰碰到了類似的問題的人。我不打算接受這個答案,因爲問題的正確答案不應該依賴於npm請求包。如果有人知道如何做到這一點,請張貼另一個答案,我會接受。