2017-11-22 6 views
5

大きすぎるHTTPリソースのダウンロードを中止するようにsimplified HTTP request() client packageを設定します。ノード内の単純化されたHTTP要求のコンテンツ長応答を制限する方法は?

URLをダウンロードするためにrequest()がセットアップされ、リソースサイズが5ギガバイトであるとします。私はrequest()が10MB後にダウンロードを停止したいと思います。通常、リクエストが応答を受け取ると、すべてのHTTPヘッダーとすべてのものが取得されます。データを操作すると、既にダウンロードされたすべてのデータがあります。

axiosにはmaxContentLengthというパラメータがありますが、request()と似たものは見つかりません。

私はエラーをキャッチするのではなく、少なくともヘッダーとリソースの始めだけをダウンロードすることを言及する必要があります。

+1

はこのヘルプをい 解凍するgzipのオプションが必要ですか? - https://stackoverflow.com/questions/15636095/how-to-limit-response-length-with-http-request-in-node-js – Jackthomson

+0

ありがとうございますが、リクエストと呼ばれるパッケージを使用していますnodejs HTTPリクエストのバージョン。それにもかかわらず、答えが得られない場合は、リクエストパッケージをノードからのHTTPリクエストに置き換える必要があるため、あなたの答えは役に立つかもしれません。 –

+1

あなたはこのパッケージについて話していますか? - https://www.npmjs.com/package/request - 上記のリンクされた答えとまったく同じように使用できない場合、このリクエストライブラリは同じ応答オブジェクトを返します。プロトタイプをオンにして、それにちょうど同じ権利をフックすることができますか?または、このライブラリはその機能を削除しますか?このライブラリは、ちょっとした構文を使って少し簡単にしているようです。そのコアでは、ノード要求と応答オブジェクトを返すだけです。 – Jackthomson

答えて

3
const request = require('request'); 
const URL = 'http://de.releases.ubuntu.com/xenial/ubuntu-16.04.3-desktop-amd64.iso'; 
const MAX_SIZE = 10 * 1024 * 1024 // 10MB , maximum size to download 
let total_bytes_read = 0; 

1 - サーバーからの応答がgzip圧縮されている場合は、 gzipオプションを有効にする必要があります。 https://github.com/request/request#examples下位互換性のため、応答圧縮はデフォルトで でサポートされていません。 gzip圧縮応答を受け入れるには、gzipオプション をtrueに設定します。

request 
    .get({ 
     uri: URL, 
     gzip: true 
    }) 
    .on('error', function (error) { 
     //TODO: error handling 
     console.error('ERROR::', error); 
    }) 
    .on('data', function (data) { 
     // decompressed data 
     console.log('Decompressed chunck Recived:' + data.length, ': Total downloaded:', total_bytes_read) 
     total_bytes_read += data.length; 
     if (total_bytes_read >= MAX_SIZE) { 
      //TODO: handle exceeds max size event 
      console.error("Request exceeds max size."); 
      throw new Error('Request exceeds max size'); //stop 
     } 
    }) 
    .on('response', function (response) { 
     response.on('data', function (chunk) { 
      //compressed data 
      console.log('Compressed chunck Recived:' + chunk.length, ': Total downloaded:', total_bytes_read) 
     }); 
    }) 
    .on('end', function() { 
     console.log('Request completed! Total size downloaded:', total_bytes_read) 
    }); 

NB:サーバーが応答を圧縮するものではありませんが、まだGZIP オプション/解凍を使用する場合は、解凍チャンク&は、元のチャンクは 等しくなります。応答はそうしない圧縮されていない場合は - したがって、あなたは、応答が圧縮されている場合は あなたは解凍チャンク

2のサイズ制限を確認する必要があります( 解凍/圧縮チャンクからの)リミットチェックのいずれかの方法を行うことができます

request 
    .get(URL) 
    .on('error', function (error) { 
     //TODO: error handling 
     console.error('ERROR::', error); 
    }) 
    .on('response', function (response) { 
     response.on('data', function (chunk) { 
      //compressed data 
      console.log('Recived chunck:' + chunk.length, ': Total downloaded:', total_bytes_read) 
      total_bytes_read += chunk.length; 
      if (total_bytes_read >= MAX_SIZE) { 
       //TODO: handle exceeds max size event 
       console.error("Request as it exceds max size:") 
       throw new Error('Request as it exceds max size'); 
      } 
      console.log("..."); 
     }); 
    }) 
    .on('end', function() { 
     console.log('Request completed! Total size downloaded:', total_bytes_read) 
    }); 
2

この場合のdataイベントは、requestパッケージを使用することもできます。 (https://www.npmjs.com/package/requestで与えられた例に基づいて)のいずれかどこで圧縮されたデータを取得するか、非圧縮データを取得し、あなたがサイズのチェックを行うことができる2つの場所、

があり

var request = require("request"); 

var size = 0; 
const MAX_SIZE = 200; 
request 
    .get('http://google.com/') 
    .on('data', function(buffer){ 
     // decompressed data as it is received 

     size += buffer.length; 

     if (size > MAX_SIZE) { 
      console.log("Aborting this request as it exceeds max size") 
      this.abort(); 
     } 
     console.log("data coming"); 

    }).on('end', function() { 
     console.log('ending request') 
    }) 
    .on('response', function (response) { 
     console.log(response.statusCode) // 200 
     console.log(response.headers['content-type']) // 'image/png' 
     response.on('data', function (data) { 
      // compressed data as it is received 
      console.log('received ' + data.length + ' bytes of compressed data') 
      // you can size and abort here also if you want. 
     }) 
    }); 
を私は以下のテストされ、それが私のためにうまく働きました
1

@ジャックソンソンは、最初のコメントの回答で指摘したように、.on(data)を使用することができます。ヘッダーが必要な場合は、応答から取得してcontent-lengthヘッダーをチェックしてチャンクを開始することもできます。

腋窩参照由来。 2000年、

これはaxiosはmaxContentLength

var responseBuffer = []; 
     stream.on('data', function handleStreamData(chunk) { 
      responseBuffer.push(chunk); 

      // make sure the content length is not over the maxContentLength if specified 
      if (config.maxContentLength > -1 && Buffer.concat(responseBuffer).length > config.maxContentLength) { 
      reject(createError('maxContentLength size of ' + config.maxContentLength + ' exceeded', 
       config, null, lastRequest)); 
      } 
     }); 

部分request同等

var request = require("request"); 

const MAX_CONTENT_LENGTH = 10000000; 

var receivedLength = 0; 

var req = request.get('http://de.releases.ubuntu.com/xenial/ubuntu-16.04.3-desktop-amd64.iso') 
    .on('response', (response) => { 
     if (response.headers['content-length'] && response.headers['content-length'] > MAX_CONTENT_LENGTH) { 
      console.log("max content-length exceeded") 
      req.abort(); 
     } 
    }) 
    .on('data', (str) => { 
     receivedLength += str.length; 
     if (receivedLength > MAX_CONTENT_LENGTH) { 
      console.log("max content-length exceeded") 
      req.abort(); 
     } 
    }) 
をどのように処理するかです:

// maxContentLengthは コンテンツがmaxContentLengthが許可されたHTTP応答の最大サイズを定義します

+0

コンテンツ長ヘッダーは、個々のチャンクではなくファイルの合計サイズです。 OPは最大に達した後にダウンロードを停止したいと考えています。 – Mehari

+0

私は同意します。 OPはaxiosと 'maxContentLength'にも言及しています。応答を編集し、Axiosから参照を追加しました – Stamos

関連する問題