FastCGIを使用してnginxの背後でDjangoを実行しています。クライアントに送信された応答の一部で、ランダムなデータ破損が応答の途中で発生していることを発見しました(途中で数百バイト程度になる可能性があります)。
この時点で、私はそれをnginxのFastCGIハンドラーまたはDjangoのFastCGIハンドラーのバグ(つまり、おそらくflupのバグ)に絞り込みました。スタンドアロン(つまりrunserver
)モードでDjangoサーバーを実行すると、この問題は発生しないためです。FastCGIモードでのみ発生します。
その他の興味深い傾向:
より大きな応答で発生する傾向があります。クライアントが初めてログインすると、1 MBのチャンクがサーバーDBに同期するために送信されます。最初の同期後、応答ははるかに小さくなります(通常、一度に数KB)。破損は常に、最初に送信された1MBのチャンクで発生しているようです。
これは、クライアントがLANを介してサーバーに接続されている場合(つまり、低遅延、高帯域幅接続)に頻繁に発生します。これにより、nginxまたはflupには、データレートの増加によって悪化するある種の競合状態があると思います。
現時点では、応答ヘッダーにSHA1ダイジェストを追加し、ヘッダーが本文のチェックサムと一致しない場合にクライアントに応答を拒否させることで、これを回避する必要がありましたが、これは恐ろしい解決策の一種です。
他の誰かがこのようなことを経験しましたか、または適切なチームにバグを報告できるように、ここで問題があるのがflupであるかnginxであるかを識別する方法に関する指針がありますか?
助けてくれてありがとう。
注:私も同様にlighttpd + FastCGI + Djangoに同様のバグを投稿しました:https : //stackoverflow.com/questions/3714489/lighttpd-fastcgi-django-truncated-response-sent-to-client-due-to -予期しない ...これは同じことではありませんが(切り捨てvs破損)、一般的な原因はWebサーバーではなくflup / Djangoであるように見え始めています。
編集:私の環境もメモする必要があります:
Mac Mini上のOSX 10.6.6
Python 2.6.1(システム)
Django 1.3(公式のtarballから)
flup 1.0.2(flupサイトのPython eggから)
nginx + ssl 1.0.0(Macportsから)
編集:Jerzykのコメントに応じて、応答を組み立てるコードパスは次のようになります(簡潔にするために編集されています)。
# This returns an objc NSData object, which is an array.array
# when pushed through the PyObjC bridge
ret = handler( request )
response = HttpResponse( ret )
response[ "Content-Length" ] = len( ret )
return response
これに基づいてContent-Lengthが間違っている可能性はないと思います。AFAIKには、Django HttpResponseオブジェクトをテキストではなく明示的にバイナリとしてマークする方法はありません。また、この問題は断続的にしか発生しないため、それが原因であるとは考えられません。
EDIT @ionelmc:DjangoでContent-Lengthを設定する必要があります-次の例のように、明示的にContent-Lengthの設定を無効にすると、nginxはこれを設定しません。
$ curl -i http://localhost/io/ping
HTTP/1.1 200 OK
Server: nginx/1.0.0
Date: Thu, 23 Jun 2011 13:37:14 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
AKSJDHAKLSJDHKLJAHSD