Yo uso nginx 1.2.3 para proxy a un script:
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8880;
proxy_buffering off;
proxy_read_timeout 300s;
gzip off;
Los scripts envían ambos Transfer-encoding: chunked
y Content-Length: 251
:
HTTP/1.0 307 Temporary Redirect
Content-length: 251
Pragma: no-cache
Location: /...
Cache-control: no-cache
Transfer-encoding: chunked
Necesito ambos, pero nginx elimina automáticamente el 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, los clientes no esperan a que se envíen los fragmentos. Esto solía funcionar con una versión anterior de nginx.
Respuestas:
Desafortunadamente, no puedo comentar sobre la publicación de cnst, así que voy a responder aquí.
El
nginx_http_proxy
módulo por defecto habla con el upstream en HTTP / 1.0. Esto se puede cambiar con la directivaproxy_http_version 1.1
.Esta también podría ser la causa de que su script devuelva una respuesta HTTP / 1.0, aunque la codificación fragmentada y el código de estado
307
no existen en esta versión.Tampoco debe usar la codificación fragmentada con una redirección , ya que esto realmente no tiene sentido.
Además , parece que nginx no pasa trozos del flujo ascendente al cliente uno por uno, pero amortigua la respuesta del flujo ascendente . El
Content-Length
campo de encabezado se ignora porque está en contra de la definición. Tuve que mirar el código fuente del módulo porque todo esto parece no estar documentado.Es posible que desee probar el
nginx_tcp_proxy_module
proxy del contenido fragmentado como datos TCP sin procesar: Módulo en GithubACTUALIZACIÓN (10.04.14)
El
nginx_http_proxy
módulo tiene soporte paraX-Accel-*
encabezados , de los cuales uno (X-Accel-Buffering: yes|no
) controla si la respuesta debe ser almacenada o no.Agregar este encabezado (
X-Accel-Buffering: no
) a la respuesta del backend hará que nginx pase directamente fragmentos al cliente.Este encabezado permite controlar el almacenamiento en búfer por solicitud .
El módulo también tiene una directiva de configuración
proxy_buffering
para habilitar o deshabilitar el almacenamiento en búfer de respuesta (no almacenar en búfer significa que el envío de fragmentos funcionará).El búfer de proxy (basado tanto en encabezado como en directivas) se documenta aquí .
fuente
nginx_tcp_proxy_module
. Funciona con algunos navegadores solo porque son muy tolerantes a errores.Como Lukas alude, HTTP 1.1 prohíbe
Content-Length
si hay unTransfer-Encoding
conjunto.Citando http://www.ietf.org/rfc/rfc2616.txt :
fuente
En primer lugar, no ha explicado específicamente por qué su script necesita codificación fragmentada, especialmente con una respuesta de redireccionamiento.
Veo una multitud de problemas aquí.
Transfer-Encoding: chunked
es unaHTTP/1.1
función (y su script parece estar respondiendo con unHTTP/1.0
encabezado)no hay
307
enHTTP/1.0
el propósito de esto
chunked
es que no sabes cuálContent-Length
hubiera sido tu, por lo tanto,chunked
se usa en lugar de proporcionar la longitud dentroContent-Length
, donde las longitudes se proporcionan dentro del cuerpo de la respuesta, entremezcladas con el contenido real; no tendría sentido que un script genere ambos encabezados por adelantadoNo estoy familiarizado personalmente
chunked
, pero según la información básica en http://en.wikipedia.org/wiki/Chunked_transfer_encoding y también http://tools.ietf.org/html/rfc2616#section-3.6.1 , Supongo que el manejo completo de la secuencia de comandos de la codificación fragmentada puede ser completamente incorrecto.Si lo anterior aún no lo cubre, y en realidad de lo contrario, tampoco está claro por qué una respuesta con un código de estado
307
o302
http debe proporcionarse con una codificación "extraña". Recientemente hubo una discusión similar en la lista de correo de nginx410 Gone
y otras páginas de error siempre excluidas de lagzip
compresión, y creo que el sentimiento se aplicaría igualmente aquí. ( http://mailman.nginx.org/pipermail/nginx/2013-March/037890.html )fuente
Tuve el mismo problema al transmitir archivos mp4 a través de la etiqueta de video html5.
Safari y Firefox se comportaron normalmente mientras que Chrome estaba activando ERR_CONTENT_LENGTH_MISMATCH en algún momento (pero me permitió ver varios minutos del video antes de fallar).
El problema no se reprodujo después de que apagué el control de caché para archivos mp4.
fuente
Compartiendo esta respuesta, publiqué en SO en caso de que sea útil: /programming/50499637/mp4-video-safari-cloudflare-nginx-rails-no-play/59348509#59348509
Tuve un problema similar con la reproducción de mp4 debido a que no se sirvieron fragmentos, y confirmó el problema según la guía de Apple, que se enumera a continuación. Verifiqué que estaba descargando todo el archivo, y después de la corrección a continuación, solo el primer fragmento.
Resolví mi reproducción de Safari .mp4 cambiando mi configuración de compresión gzip en mi nginx.conf, para eliminar la compresión gzip de archivos .mp4 .
Aquí está el bloque en nginx para referencia. (Nota: dependiendo de cómo esté configurada su aplicación, es posible que deba cambiar la línea de ubicación a
location ~ \.mp4$ {
Enlace a la referencia de documentación de Apple: https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html#//apple_ref/doc/uid/TP40006514-SW6
fuente