gunicornで実行されているPythonアプリケーションのフロントエンドとしてnginxを構成しましたが、約65kのデータが送信された後、nginxは接続を終了しています。
たとえば、次のようなビューがあります。
def debug_big_file(request):
return HttpResponse("x" * 500000)
しかし、nginxを介してそのURLにアクセスすると、65283バイトしか取得できません。
$ curl https://example.com/debug/big-file | wc
…
curl: (18) transfer closed with outstanding read data remaining
0 1 65283
gunicornに直接アクセスすると、すべてが期待どおりに機能することに注意してください。
$ curl http://localhost:1234/debug/big-file | wc
…
0 1 500000
関連するnginx設定:
location / {
proxy_pass http://localhost:1234/;
proxy_redirect off;
proxy_headers_hash_bucket_size 96;
}
nginxバージョン1.7.0
他のいくつかの事実:
- バイト数はリクエストごとに一貫していますが、コンテンツによって異なります(65,283ではなく65,372バイトの後に切り取られた大きなPNGファイルで最初に気付きました)
- 110kバイトは正しく送信され
"x" * 110000
ます(つまり、110,000バイトすべてを返します)が、120kバイトは送信されません。 tcpdump
nginxがRSTパケットをgunicornに送信していることを示唆しています。
(a)gunicornが110kから120kバイトのサイズの返信をフレームするように選択する方法、および(b)nginxが110kバイトから120kバイトのサンプルペイロードサイズの同じ範囲に対してフレーミングを選択する方法を確認すると役立ちます。HTTPがデータをフレーム化できる3つの方法:コンテンツの長さを提供します。チャンクエンコーディングを行います。または、ボディが完成したときにソケットを閉じることを約束する以外は、フレーミングを一切行いません。
—
ブランドンロードス
content-lengthヘッダーが提供されています。...私はそれ以外の場合は両者の間に何が起こっているのか確認するためにダンプパケットましょう
—
デヴィッドWolever
非常に奇妙です tcpdumpは、nginxが接続をアクティブにRST-ingしていることを示唆しています(編集を参照)。nginxもHTTP / 1.0およびを使用しています
—
デビッドウォレバー
Connection: close
。また、Content-Length
ヘッダーが正しいことも確認しました。