Tengo nginx configurado como front-end para una aplicación Python que se ejecuta bajo gunicorn, pero nginx está finalizando las conexiones después de que se hayan enviado aproximadamente 65k de datos.
Por ejemplo, tengo una vista que se ve así:
def debug_big_file(request):
return HttpResponse("x" * 500000)
Pero cuando accedo a esa URL a través de nginx, solo obtengo 65283 bytes:
$ curl https://example.com/debug/big-file | wc
…
curl: (18) transfer closed with outstanding read data remaining
0 1 65283
Tenga en cuenta que todo funciona como se espera al acceder directamente a gunicorn:
$ curl http://localhost:1234/debug/big-file | wc
…
0 1 500000
La configuración de nginx relevante:
location / {
proxy_pass http://localhost:1234/;
proxy_redirect off;
proxy_headers_hash_bucket_size 96;
}
Y nginx versión 1.7.0
Algunos otros hechos:
- El número de bytes es consistente de solicitud a solicitud, pero varía según el contenido (lo noté por primera vez con un archivo PNG grande, que se cortó después de 65,372 bytes, no 65,283)
- 110k bytes se envían correctamente (es decir,
"x" * 110000
devuelve todos los 110,000 bytes), pero 120k bytes no son tcpdump
sugiere que nginx está enviando un paquete RST a gunicorn:
Sería útil ver (a) cómo gunicorn está eligiendo enmarcar las respuestas de 110k a 120k bytes de tamaño, y (b) cómo nginx elige su encuadre para el mismo rango de tamaños de carga útil de muestra entre 110k y 120k bytes. Las tres formas en que HTTP puede enmarcar datos: proporcionar longitud de contenido; hacer codificación fragmentada; o no enmarque, excepto para prometer cerrar el zócalo cuando el cuerpo esté completo.
—
Brandon Rhodes
Se proporciona un encabezado de longitud de contenido. Permítanme volcar el paquete para ver qué está pasando entre los dos, de lo contrario ...
—
David Wolever
Hrm, muy raro. tcpdump sugiere que nginx está activando la conexión RST (ver edición). nginx también está usando HTTP / 1.0 y
—
David Wolever
Connection: close
. También he confirmado que el Content-Length
encabezado es correcto.