Ich verwende Django hinter Nginx mit FastCGI. Ich habe festgestellt, dass in einigen der an den Client gesendeten Antworten zufällige Datenbeschädigungen in der Mitte der Antworten auftreten (möglicherweise einige hundert Bytes in der Mitte).
Zu diesem Zeitpunkt habe ich mich darauf beschränkt, entweder ein Fehler im FastCGI-Handler von nginx oder im FastCGI-Handler von Django zu sein (dh wahrscheinlich ein Fehler in flup), da dieses Problem nie auftritt, wenn ich den Django-Server im Standalone- runserver
Modus (dh ) ausführe . Dies geschieht nur im FastCGI-Modus.
Weitere interessante Trends:
Dies tritt tendenziell bei größeren Antworten auf. Wenn sich ein Client zum ersten Mal anmeldet, werden ihm mehrere 1-MB-Blöcke gesendet, um sie mit der Server-Datenbank zu synchronisieren. Nach dieser ersten Synchronisierung sind die Antworten viel kleiner (normalerweise jeweils einige KB). Die Beschädigung scheint immer bei den zu Beginn gesendeten 1-MB-Blöcken aufzutreten.
Dies tritt häufiger auf, wenn der Client über LAN mit dem Server verbunden ist (dh eine Verbindung mit geringer Latenz und hoher Bandbreite). Dies lässt mich denken, dass es in Nginx oder Flup eine Art Race-Bedingung gibt, die durch eine erhöhte Datenrate verschärft wird.
Im Moment musste ich das umgehen, indem ich einen zusätzlichen SHA1-Digest in den Antwortheader einfügte und den Client Antworten ablehnen ließ, bei denen der Header nicht mit der Body-Prüfsumme übereinstimmt, aber dies ist eine schreckliche Lösung.
Hat jemand anderes so etwas erlebt oder hat er Hinweise, wie man feststellen kann, ob Flup oder Nginx hier schuld sind, damit ich einen Fehler beim entsprechenden Team melden kann?
Vielen Dank im Voraus für jede Hilfe.
Hinweis: Ich habe vor einiger Zeit auch einen ähnlichen Fehler in lighttpd + FastCGI + Django hier gepostet: /programming/3714489/lighttpd-fastcgi-django-truncated-response-sent-to-client-due-to -unerwartet ... obwohl dies nicht dasselbe ist (Kürzung vs. Korruption), sieht es so aus, als ob der übliche Schuldige eher flup / Django als der Webserver ist.
Bearbeiten: Ich sollte auch beachten, was meine Umgebung ist:
OSX 10.6.6 auf einem Mac Mini
Python 2.6.1 (System)
Django 1.3 (vom offiziellen Tarball)
flup 1.0.2 (aus Python-Ei auf der Flup-Seite)
nginx + ssl 1.0.0 (von Macports)
BEARBEITEN: Als Antwort auf Jerzyks Kommentar sieht der Codepfad, der die Antwort zusammenstellt, so aus (aus Gründen der Prägnanz bearbeitet):
# 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
Ich denke nicht, dass es möglich ist, dass die Inhaltslänge aufgrund dessen falsch ist, und AFAIK gibt es keine Möglichkeit, ein Django HttpResponse-Objekt als explizit binär im Gegensatz zu Text zu markieren. Da das Problem nur zeitweise auftritt, glaube ich nicht, dass es das erklärt, sonst würden Sie es vermutlich bei jeder Anfrage sehen.
EDIT @ionelmc: Sie müssen die Inhaltslänge in Django festlegen - nginx legt dies nicht für Sie fest, wie im folgenden Beispiel gezeigt, nachdem ich die explizite Einstellung der Inhaltslänge deaktiviert habe:
$ 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