2010-10-19 10 views
20

Tengo una aplicación Django alojado a través de Nginx y uWsgi. En una solicitud muy simple, obtengo un comportamiento diferente para GET y POST, que no debería ser el caso.Nginx restablecimiento de conexión, respuesta de uWsgi perdido

El Demonio de Registro uWsgi:

[pid: 32454|app: 0|req: 5/17] 127.0.0.1() {36 vars in 636 bytes} [Tue Oct 19 11:18:36 2010] POST /buy/76d4f520ae82e1dfd35564aed64a885b/a_2/10/ => generated 80 bytes in 3 msecs (HTTP/1.0 440) 1 headers in 76 bytes (0 async switches on async core 0) 
[pid: 32455|app: 0|req: 5/18] 127.0.0.1() {32 vars in 521 bytes} [Tue Oct 19 11:18:50 2010] GET /buy/76d4f520ae82e1dfd35564aed64a885b/a_2/10/ => generated 80 bytes in 3 msecs (HTTP/1.0 440) 1 headers in 76 bytes (0 async switches on async core 0) 

El accesslog Nginx:

127.0.0.1 - - [19/Oct/2010:18:18:36 +0200] "POST /buy/76d4f520ae82e1dfd35564aed64a885b/a_2/10/ HTTP/1.0" 440 0 "-" "curl/7.19.5 (i486-pc-linux-gnu) libcurl/7.19.5 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.15" 
127.0.0.1 - - [19/Oct/2010:18:18:50 +0200] "GET /buy/76d4f520ae82e1dfd35564aed64a885b/a_2/10/ HTTP/1.0" 440 80 "-" "curl/7.19.5 (i486-pc-linux-gnu) libcurl/7.19.5 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.15" 

El registro de errores Nginx:

2010/10/19 18:18:36 [error] 4615#0: *5 readv() failed (104: Connection reset by peer) while reading upstream, client: 127.0.0.1, server: localhost, request: "POST /buy/76d4f520ae82e1dfd35564aed64a885b/a_2/10/ HTTP/1.0", upstream: "uwsgi://unix:sock/uwsgi.sock:", host: "localhost:9201" 

En esencia, Nginx pierde alguna parte de la respuesta si uso la POST , no es así si uso GET.

Alguien sabe algo al respecto?

+0

Véase también http://stackoverflow.com/questions/7273725/django-error-when-send-emails-thrue-google-apps/ 7279065 –

Respuesta

2

Después de una suerte de descubrimiento de nuevas investigaciones (http://answerpot.com/showthread.php?577619-Several%20Bugs/Page2) me encontré con algo que ayudó ...

El suministro del parámetro en el uwsgi_pass_request_body off; Nginx conf resuelve este problema ...

+7

Esto no funciona si su aplicación realmente necesita los datos POST, ¿verdad? – ehabkost

+2

Sí, esto no pasará los datos de la publicación a uwsgi. En su lugar, se debe activar la función de almacenamiento en búfer posterior. –

5

Me sale el mismo problema, pero en mi caso no puedo deshabilitar "uwsgi_pass_request_body" ya que la mayoría de las veces (pero no siempre) mi aplicación necesita los datos POST.

Esta es la solución que encontré, mientras que este número no es fijo en uwsgi: http://permalink.gmane.org/gmane.comp.python.wsgi.uwsgi.general/813

import django.core.handlers.wsgi 
class ForcePostHandler(django.core.handlers.wsgi.WSGIHandler): 
    """Workaround for: http://lists.unbit.it/pipermail/uwsgi/2011-February/001395.html 
    """ 
    def get_response(self, request): 
     request.POST # force reading of POST data 
     return super(ForcePostHandler, self).get_response(request) 

application = ForcePostHandler() 
+2

Esto realmente funcionó para mí también (en mi caso con el proyecto Flask). Básicamente, debes leer el POST antes de responder. –

+0

@VictorFarazdagi cómo hiciste eso en el frasco? – Jarek

+0

Así es como lo que acabo de hacer para solucionar este problema desagradable: Respuesta response.data – Khorkrak

23

Pass --post-buffering 1 a uwsgi

Esto amortiguará automáticamente todo el cuerpo http> 1 byte

El problema se plantea por la forma en que nginx gestiona las desconexiones aguas arriba

+0

-1: ¿Agregar opción a qué? nginx? uwsgi? –

+0

Esta es una opción UWSGI, y funciona para mí también. – freb

+2

FWIW, @roberto es el autor de uwsgi. –

5

Estoy enfrentando los mismos problemas. Intenté todas las soluciones anteriores, pero no estaban funcionando. Ignorar el cuerpo de respuesta en mi caso simplemente no es una opción.

Al parecer se trata de un error con nginx and uwsgi when dealing with POST requests whose response is smaller than 4052 bytes

Lo resuelto por mí estaba añadiendo "--pep3333-entrada" a la lista de parámetros de uwsgi. Después de eso, todos los POST se devuelven correctamente.

Versiones de nginx/uwsgi que estoy usando:

$ nginx -V 
nginx: nginx version: nginx/0.9.6 

$ uwsgi --version 
uWSGI 0.9.7 
+0

Gracias por la respuesta. Simplemente agregando "--pep3333-input" a uwsgi no lo solucionó. También tuve que agregar "--post-buffering 4096" como se hace referencia aquí: http://comments.gmane.org/gmane.comp.python.wsgi.uwsgi.general/812 – freb

+0

Según Roberto, el '--pep3333 -input' ahora está obsoleto y no hace nada en las versiones más recientes de uwsgi. Quité la bandera y las cosas siguen funcionando correctamente. Quizás estás enfrentando algún otro problema que lograste resolver con '--post-buffering'? – lullis

+0

Si el problema en la pregunta es el mismo que tuve, el problema fue que si tu código python nunca lee los datos POST (en django, esto sería acceder a request.POST en algún lugar de tu vista), entonces las cosas se ponen jodido. Si le dices a UWSGI que proteja los datos POST con el parámetro --post-buffering 1 como dice roberto, entonces tus solicitudes POST no generarán errores sin importar lo que estés haciendo en tu vista. – freb

Cuestiones relacionadas