2017-11-22 1 views
5

simplified HTTP request() client package을 설치하여 너무 큰 HTTP 리소스 다운로드를 중단하고 싶습니다.노드에서 단순화 된 HTTP 요청의 콘텐츠 길이 응답을 제한하는 방법은 무엇입니까?

url을 다운로드하기 위해 request()가 설정되었고 리소스 크기가 5 기가 바이트라고 가정 해 봅시다. 요청()이 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

이 경우에도 request 패키지의 data 이벤트를 사용할 수 있습니다. 나는 아래의 테스트하고 나를 위해

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. 
     }) 
    }); 

당신이 크기 검사를 할 수있는이 곳은 당신이 압축 된 데이터를 얻을 수 또는 압축되지 않은 데이터를 얻을 곳 곳 중 하나 (https://www.npmjs.com/package/request에서 주어진 예 기준)이 있습니다

를 괜찮 았는데
1

@ Jackthomson이 첫 번째 주석의 답을 지적한대로 .on(data)을 사용하여 수행 할 수 있습니다. 헤더를 원할 경우 응답에서 가져올 수 있으며 content-length 헤더를 확인하고 청크 시작을 확인할 수도 있습니다.

액시오 참고서에서.

// maxContentLength

는 maxContentLength 허용되는 HTTP 응답 내용의 최대 크기를 정의합니다

이 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 동등한 처리하는 방법이며, 2000

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(); 
     } 
    }) 
+0

콘텐츠 길이 헤더는 개별 청크가 아닌 파일의 전체 크기입니다. 최대 거리에 도달 한 후에 OP는 다운로드를 중단하려고합니다. – Mehari

+0

동의합니다. OP는 axios와 'maxContentLength'도 언급합니다. 응답을 수정하고 axios에서 참조를 추가했습니다. – Stamos

관련 문제