Eu tenho o nginx configurado como um front-end para um aplicativo Python em execução no gunicorn, mas o nginx está encerrando as conexões após o envio de cerca de 65k de dados.
Por exemplo, eu tenho uma visão parecida com esta:
def debug_big_file(request):
return HttpResponse("x" * 500000)
Mas quando eu acesso esse URL através do nginx, recebo apenas 65283 bytes:
$ curl https://example.com/debug/big-file | wc
…
curl: (18) transfer closed with outstanding read data remaining
0 1 65283
Observe que tudo funciona como esperado ao acessar o gunicorn diretamente:
$ curl http://localhost:1234/debug/big-file | wc
…
0 1 500000
A configuração nginx relevante:
location / {
proxy_pass http://localhost:1234/;
proxy_redirect off;
proxy_headers_hash_bucket_size 96;
}
E nginx versão 1.7.0
Alguns outros fatos:
- O número de bytes é consistente de solicitação para solicitação, mas varia de acordo com o conteúdo (notei pela primeira vez com um arquivo PNG grande, cortado após 65.372 bytes, e não 65.283)
- 110k bytes são enviados corretamente (ou seja,
"x" * 110000
retorna todos os 110.000 bytes), mas 120k bytes não são tcpdump
sugere que o nginx está enviando um pacote RST ao gunicorn:
Seria útil ver (a) como o gunicorn está escolhendo enquadrar respostas de 110k a 120k bytes de tamanho e (b) como o nginx escolhe seu enquadramento para o mesmo intervalo de tamanhos de amostra de carga útil entre 110k e 120k bytes. As três maneiras pelas quais o HTTP pode enquadrar dados: fornecer comprimento do conteúdo; fazer codificação em pedaços; ou não dê nenhuma moldura, exceto prometer fechar o encaixe quando o corpo estiver completo.
—
Brandon Rhodes
Um cabeçalho de comprimento de conteúdo está sendo fornecido. Deixe-me pacote despejar para ver o que está acontecendo entre os dois caso contrário ...
—
David Wolever
Hum, muito estranho. O tcpdump sugere que o nginx está ativamente fazendo o RST da conexão (consulte editar). O nginx também está usando HTTP / 1.0 e
—
David Wolever
Connection: close
. Também confirmei que o Content-Length
cabeçalho está correto.