J'utilise nginx 1.2.3 pour proxy vers un script:
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8880;
proxy_buffering off;
proxy_read_timeout 300s;
gzip off;
Le script envoie les deux Transfer-encoding: chunked
et Content-Length: 251
:
HTTP/1.0 307 Temporary Redirect
Content-length: 251
Pragma: no-cache
Location: /...
Cache-control: no-cache
Transfer-encoding: chunked
J'ai besoin des deux, mais nginx supprime automatiquement 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: /...
Par conséquent, les clients n'attendent pas l'envoi des morceaux. Cela fonctionnait avec une version antérieure de nginx.
Réponses:
Malheureusement, je ne peux pas commenter le post du cnst - je vais donc répondre ici.
Le
nginx_http_proxy
module parle par défaut avec l'amont en HTTP / 1.0. Cela peut être changé avec la directiveproxy_http_version 1.1
.Cela peut également être la raison pour laquelle votre script retourne une réponse HTTP / 1.0, bien que le codage en morceaux et le code d'état
307
n'existent pas dans cette version.Vous ne devriez pas non plus utiliser de codage fragmenté avec une redirection , car cela n'a pas vraiment de sens.
De plus , il semble que nginx ne transmette pas les morceaux de l'amont au client un par un, mais il tamponne la réponse de l'amont . Le
Content-Length
champ d'en-tête est ignoré car il est contraire à la définition. J'ai dû regarder le code source du module car tout cela ne semble pas documenté.Vous voudrez peut-être essayer de mettre
nginx_tcp_proxy_module
en proxy le contenu fragmenté en tant que données TCP brutes: Module sur GithubMISE À JOUR (10.04.14)
Le
nginx_http_proxy
module prend en charge les en-X-Accel-*
têtes , dont un (X-Accel-Buffering: yes|no
) contrôle si la réponse doit être mise en mémoire tampon ou non.L'ajout de cet en-tête (
X-Accel-Buffering: no
) à la réponse du backend fera que nginx passera directement des morceaux au client.Cet en-tête permet de contrôler la mise en mémoire tampon à la demande .
Le module dispose également d'une directive de configuration
proxy_buffering
pour activer ou désactiver la mise en mémoire tampon des réponses (la mise en mémoire tampon ne signifie pas que l'envoi de blocs fonctionnera).La mise en mémoire tampon du proxy (basée sur l'en-tête et la directive) est documentée ici .
la source
nginx_tcp_proxy_module
. Il fonctionne avec certains navigateurs uniquement parce qu'ils sont très tolérants aux erreurs.Comme Lukas le pense, HTTP 1.1 interdit
Content-Length
s'il y a unTransfer-Encoding
ensemble.Citant http://www.ietf.org/rfc/rfc2616.txt :
la source
Vous n'avez pas spécifiquement expliqué pourquoi votre script a besoin d'un codage fragmenté en premier lieu, en particulier avec une réponse de redirection.
Je vois ici une multitude de problèmes.
Transfer-Encoding: chunked
est uneHTTP/1.1
fonctionnalité (et votre script semble répondre avec un en-HTTP/1.0
tête)il n'y a pas
307
dansHTTP/1.0
le seul but de
chunked
est que vous ne savez pas ce que vousContent-Length
auriez été, donc,chunked
est utilisé au lieu de fournir la longueur à l'intérieurContent-Length
, alors que les longueurs sont fournies dans le corps de la réponse, mélangées avec le contenu réel; il serait inutile qu'un script génère à l'avance les deux en-têtesJe ne connais pas personnellement
chunked
, mais selon les informations de base sur http://en.wikipedia.org/wiki/Chunked_transfer_encoding et également http://tools.ietf.org/html/rfc2616#section-3.6.1 , Je dirais que la gestion complète de votre script de l'encodage en morceaux peut être complètement fausse.Si ce qui précède ne le couvre toujours pas, et en réalité dans le cas contraire, il est également difficile de savoir pourquoi une réponse avec un code d'état
307
ou302
http doit être fournie avec un codage "bizarre". Il y a eu récemment une discussion similaire dans la liste de diffusion nginx410 Gone
et d'autres pages d'erreur toujours exclues de lagzip
compression, et je pense que le sentiment s'appliquerait également ici. ( http://mailman.nginx.org/pipermail/nginx/2013-March/037890.html )la source
J'ai eu le même problème de streaming de fichier mp4 via la balise vidéo html5.
Safari et Firefox se sont comportés normalement tandis que Chrome déclenchait ERR_CONTENT_LENGTH_MISMATCH à un moment donné (mais cela m'a permis de regarder plusieurs minutes de la vidéo avant d'échouer).
Le problème ne s'est pas reproduit après avoir désactivé le contrôle du cache pour les fichiers mp4.
la source
Partageant cette réponse, j'ai posté sur SO au cas où cela serait utile: /programming/50499637/mp4-video-safari-cloudflare-nginx-rails-no-play/59348509#59348509
J'ai eu un problème similaire avec la lecture mp4 en raison de la non-diffusion de morceaux, et j'ai confirmé le problème selon le guide d'Apple, répertorié ci-dessous. J'ai vérifié que je téléchargeais le fichier entier, et après la correction ci-dessous, seul le premier morceau.
J'ai résolu ma lecture Safari .mp4 en modifiant mes paramètres de compression gzip dans mon nginx.conf, pour supprimer la compression gzip des fichiers .mp4 .
Voici le bloc dans nginx pour référence. (Remarque: selon la configuration de votre application, vous devrez peut-être modifier la ligne de
location ~ \.mp4$ {
Lien vers la référence de la documentation Apple: https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html#//apple_ref/doc/uid/TP400014
la source