2017-12-28 8 views
6

私はdjangoで内部のhttpサービスに接続したいので、内容が非常に大きいので、これらのサービスのhttp応答をバッファリングする必要があります。IterableオブジェクトとDjango StreamingHttpResponse

私のpython 3.6を使用して、2.0ジャンゴ、http.client次のコードています:、

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

、すべてが正常に動作します:

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 

そしてREPONSEが空で、私はイテレータをテストしますなぜ動作しているのか分かりません。

+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/

まず、いくつかの条件を満たしている必要があります

  • クライアントがリクエストメソッドが応答がないHEAD
  • ませんでしたHTTP/1.1以降
  • を話すしなければなりませんContent-Lengthヘッダーを含まない
  • これらの条件に該当する場合は、応答ステータスは、その後、Gunicornは応答が チャンクでストリーミングするクライアントへのシグナリング、 応答にTransfer-Encoding: chunkedヘッダを追加しますない204または304

ました。

あなたがHttpResponseを使用していても、実際にはGunicornはTransfer-Encoding: chunkedと応答します。

実際に応答をストリーミングするには、 個でクライアントに送信するには、条件が真でなければならず、応答は複数の項目で 繰り返し可能である必要があります。

基本的に、ストリーミングまたはContent-Lengthを決定する必要があります。

再開可能なダウンロードを使用する場合は、Rangeを使用してください。

+0

これはほかのWSGIサーバーにも適用されますか? – dahrens

+0

IDK、私は実験しませんでした。 –

0

最後に、問題はHTTPリクエストが数ミリ秒後に切断されるということでした。なぜなら、接続後、オブジェクトの作成が動作する前に反復処理を行うと、レスポンス後に使用しないときですしかし、繰り返しを開始するときに接続を開始すると、すべてが完璧に動作します。

乾杯。

関連する問題