2017-12-28 35 views
6

django를 사용하여 내부 http 서비스에 연결하고 일부 내용이 매우 크기 때문에 해당 서비스의 http 응답을 버퍼링해야합니다.Iterable 객체와 Django StreamingHttpResponse

내가 파이썬 3.6, 장고 2.0, http.client를 사용하고

다음과 같은 코드 :

class HTTPStreamIterAndClose(): 
    def __init__(self, conn, res, buffsize): 
     self.conn = conn 
     self.res = res 
     self.buffsize = buffsize 
     self.length = 1 

     bytes_length = int(res.getheader('Content-Length')) 

     if buffsize < bytes_length: 
      self.length = math.ceil(bytes_length/buffsize) 

    def __iter__(self): 
     return self 

    def __next__(self): 
     buff = self.res.read(self.buffsize) 

     if buff is b'': 
      self.res.close() 
      self.conn.close() 

      raise StopIteration 
     else: 

      return buff 

    def __len__(self): 
     return self.length 


def passthru_http_service(request, server, timeout, path): 
    serv = HTTPService(server, timeout) 
    res = serv.request(path) 

    response = StreamingHttpResponse(
     HTTPStreamIterAndClose(serv.connection, res, 200), 
     content_type='application/json' 
    ) 
    response['Content-Length'] = res.getheader('Content-Length') 

    return response 

그리고 리스폰스, 내가 가진 반복자 테스트 비어 :

b''.join(HTTPStreamIterAndClose(serv.connection, res, 200) 

을 그리고 모든 것이 잘 작동, 나는 왜 일하지 않는지 모른다.

+0

브라우저 콘솔에 오류가 있습니까? – xyres

+0

아니요, 오류가 없습니다 –

+0

"작동하지 않는다"는 것을 의미합니까? 당신은 http 500를 얻는가? 200 빈 출력? 질문에'curl -v http : // localhost : 8000/x/y /'(또는 Postman 또는 ...) 출력을 제공하십시오. –

답변

4

https://andrewbrookins.com/django/how-does-djangos-streaminghttpresponse-work-exactly/

첫째, 몇 가지 조건이 충족되어야합니다 클라이언트가 HTTP/1.1 이상 요청 방법은 응답이 수행하는 HEAD

  • 아니었다
  • 말하기해야

    • Content-Length 헤더를 포함하지 않음
    • 응답 상태가되지 204 또는 304 이러한 조건에 해당하는 경우

    , 다음 Gunicorn는 응답이 덩어리로 스트리밍 할 것을 클라이언트에 신호의 응답에 Transfer-Encoding: chunked 헤더를 추가한다이었다.

    사실, Gunicorn은 을 사용했는데 그 조건이 맞다면 Transfer-Encoding: chunked으로 응답 할 것입니다.

    실제로 응답을 스트리밍하려면 조각으로 클라이언트에 보내려면 조건이 참이어야하며 응답은 복수 항목으로 반복 가능해야합니다.

  • 기본적으로 스트리밍 또는 Content-Length을 결정해야합니다.

    재개 가능한 다운로드를 원하시면 Range을 사용하십시오.

    +0

    이것은 다른 WSGI 서버에도 적용됩니까? – dahrens

    +0

    IDK, 실험하지 않았습니다. –

    0

    결국 문제는 HTTP 요청이 일부 ms 후에 연결이 끊어 졌음을 의미합니다. 연결 후 inmediatly를 반복 할 때와 객체 생성이 작동하기 전에 내가 응답 후에 사용하지 않는 이유는 무엇입니까? ,하지만 반복을 시작할 때 연결을 시작하면 모든 것이 완벽하게 작동합니다. /.

    건배.