Eu uso o nginx 1.2.3 para fazer proxy de um script:
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8880;
proxy_buffering off;
proxy_read_timeout 300s;
gzip off;
Os scripts enviam ambos Transfer-encoding: chunked
e Content-Length: 251
:
HTTP/1.0 307 Temporary Redirect
Content-length: 251
Pragma: no-cache
Location: /...
Cache-control: no-cache
Transfer-encoding: chunked
Eu preciso dos dois, mas o nginx remove automaticamente o Content-Length
:
HTTP/1.1 302 Found
Server: nginx/1.2.3
Content-Type: application/json; charset=utf-8
Content-Length: 58
Connection: keep-alive
Location: /...
Como resultado, os clientes não esperam o envio dos pedaços. Isso costumava funcionar com uma versão anterior do nginx.
Respostas:
Infelizmente, não posso comentar na postagem do cnst - por isso vou responder aqui.
O
nginx_http_proxy
módulo, por padrão, conversa com o upstream no HTTP / 1.0. Isso pode ser alterado com a diretivaproxy_http_version 1.1
.Isso também pode ser a causa do seu script retornar uma resposta HTTP / 1.0, embora a codificação em partes e o código de status
307
não existam nesta versão.Você também não deve usar a codificação em blocos com um redirecionamento , pois isso realmente não faz sentido.
Além disso , parece que o nginx não passa pedaços do upstream para o cliente um por um, mas armazena em buffer a resposta do upstream . O
Content-Length
campo do cabeçalho é ignorado porque é contra a definição. Eu tive que olhar para o código fonte do módulo, porque tudo isso parece estar sem documentos.Você pode experimentar o
nginx_tcp_proxy_module
proxy do conteúdo em blocos como dados TCP brutos: Módulo no GithubUPDATE (10.04.14)
O
nginx_http_proxy
módulo possui suporte paraX-Accel-*
cabeçalhos , dos quais um (X-Accel-Buffering: yes|no
) controla se a resposta deve ser armazenada em buffer ou não.Adicionar este cabeçalho (
X-Accel-Buffering: no
) à resposta do back-end fará com que o nginx passe diretamente os pedaços para o cliente.Este cabeçalho permite controlar o buffer em uma base por solicitação .
O módulo também possui uma diretiva de configuração
proxy_buffering
para habilitar ou desabilitar o buffer de resposta (sem buffer significa que o envio de chunks funcionará).O buffer de proxy (baseado em cabeçalho e diretiva) está documentado aqui .
fonte
nginx_tcp_proxy_module
. Ele funciona com alguns navegadores apenas porque são muito tolerantes a erros.Como Lukas aludiu, o HTTP 1.1 proíbe
Content-Length
se houver umTransfer-Encoding
conjunto.Citando http://www.ietf.org/rfc/rfc2616.txt :
fonte
Você não detalhou especificamente por que seu script precisa de codificação em partes, principalmente com uma resposta de redirecionamento.
Eu vejo uma infinidade de problemas aqui.
Transfer-Encoding: chunked
é umHTTP/1.1
recurso (e seu script parece estar respondendo com umHTTP/1.0
cabeçalho)não existe
307
emHTTP/1.0
o objetivo de todo
chunked
é que você não sabe qualContent-Length
teria sido, portanto,chunked
é usado no lugar de fornecer o comprimento internoContent-Length
, onde os comprimentos são fornecidos no corpo da resposta, misturados com o conteúdo real; seria inútil que um script gere ambos os cabeçalhos antecipadamenteNão conheço pessoalmente
chunked
, mas de acordo com as informações básicas em http://en.wikipedia.org/wiki/Chunked_transfer_encoding e também http://tools.ietf.org/html/rfc2616#section-3.6.1 , Eu suponho que o manuseio completo da codificação em partes do seu script possa estar completamente errado.Se o que foi dito acima ainda não o abordar, e em toda a atualidade, também não está claro por que uma resposta com um código de status
307
ou302
http deve ser fornecida com uma codificação "estranha". Recentemente, houve uma discussão semelhante na lista de discussão nginx sobre410 Gone
e outras páginas de erro sempre excluídas dagzip
compactação, e acho que o sentimento se aplicaria igualmente aqui. ( http://mailman.nginx.org/pipermail/nginx/2013-March/037890.html )fonte
Eu tive o mesmo problema de streaming de arquivo mp4 através da tag de vídeo html5.
O Safari e o Firefox se comportaram normalmente, enquanto o Chrome estava acionando o ERR_CONTENT_LENGTH_MISMATCH em algum momento (mas me permitiu assistir vários minutos do vídeo antes de falhar).
O problema não foi reproduzido depois que eu desliguei o controle de cache para arquivos mp4.
fonte
Compartilhando esta resposta, publiquei na SO caso seja útil: /programming/50499637/mp4-video-safari-cloudflare-nginx-rails-no-play/59348509#59348509
Eu tive um problema semelhante com a reprodução de mp4 devido à falta de veiculação de pedaços e confirmei o problema pelo guia da Apple, listado abaixo. Eu verifiquei que estava baixando o arquivo inteiro e, após a correção abaixo, apenas o primeiro pedaço.
Resolvi minha reprodução .mp4 do Safari alterando minhas configurações de compactação gzip no meu nginx.conf, para remover a compactação gzip dos arquivos .mp4 .
Aqui está o bloco no nginx para referência. (Observação: dependendo de como seu aplicativo está configurado, pode ser necessário alterar a linha de localização para
location ~ \.mp4$ {
Link para a referência de documentação da Apple: https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html#//apple_ref/doc/uid/TP40006514-Windows
fonte