Używam nginx 1.2.3 do proxy do skryptu:
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8880;
proxy_buffering off;
proxy_read_timeout 300s;
gzip off;
Skrypty wysyła zarówno Transfer-encoding: chunked
a Content-Length: 251
:
HTTP/1.0 307 Temporary Redirect
Content-length: 251
Pragma: no-cache
Location: /...
Cache-control: no-cache
Transfer-encoding: chunked
Potrzebuję obu, ale nginx automatycznie usuwa 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: /...
W rezultacie klienci nie czekają na wysłanie porcji. To działało z wcześniejszą wersją nginx.
Odpowiedzi:
Niestety nie mogę komentować postu cnst - więc odpowiem tutaj.
nginx_http_proxy
Moduł domyślnie rozmów z Upstream w HTTP / 1.0. Można to zmienić za pomocą dyrektywyproxy_http_version 1.1
.Może to być również przyczyną, dla której skrypt zwraca odpowiedź HTTP / 1.0, chociaż
307
w tej wersji nie istnieje kodowanie dzielone i kod statusu .Nie powinieneś także używać kodowania fragmentarycznego z przekierowaniem , ponieważ tak naprawdę nie ma to sensu.
Dodatkowo wygląda na to, że nginx nie przekazuje fragmentów od klienta do klienta jeden po drugim, ale buforuje odpowiedź użytkownika . Pole
Content-Length
nagłówka jest ignorowane, ponieważ jest niezgodne z definicją. Musiałem spojrzeć na kod źródłowy modułu, ponieważ wszystko to wydaje się nieudokumentowane.Możesz wypróbować
nginx_tcp_proxy_module
proxy do fragmentacji jako surowych danych TCP: Moduł w GithubUPDATE (10/04/14) moduł obsługuje nagłówków , z których jeden ( ) określa, czy odpowiedź powinna być buforowane lub nie.
nginx_http_proxy
X-Accel-*
X-Accel-Buffering: yes|no
Dodanie tego nagłówka (
X-Accel-Buffering: no
) do odpowiedzi backendu spowoduje, że nginx bezpośrednio przekaże porcje do klienta.Ten nagłówek pozwala kontrolować buforowanie na podstawie żądania .
Moduł ma również dyrektywę konfiguracji,
proxy_buffering
która włącza lub wyłącza buforowanie odpowiedzi (brak buforowania oznacza, że wysyłanie porcji będzie działać).Buforowanie proxy (zarówno na podstawie nagłówka, jak i dyrektywy) jest tutaj udokumentowane .
źródło
nginx_tcp_proxy_module
. Działa tylko z niektórymi przeglądarkami, ponieważ są one bardzo odporne na błędy.Jak wspominał Lukas, HTTP 1.1 zabrania,
Content-Length
jeśli istniejeTransfer-Encoding
zestaw.Cytując http://www.ietf.org/rfc/rfc2616.txt :
źródło
Nie wyjaśniłeś szczegółowo, dlaczego twój skrypt wymaga kodowania fragmentarycznego, zwłaszcza z odpowiedzią przekierowującą.
Widzę tu wiele problemów.
Transfer-Encoding: chunked
jestHTTP/1.1
funkcją (a skrypt wydaje się odpowiadać za pomocąHTTP/1.0
nagłówka)nie ma
307
wHTTP/1.0
cały ten cel
chunked
polega na tym, że nie wiesz, coContent-Length
byś był, więcchunked
został użyty zamiast podania długości w środkuContent-Length
, gdzie zamiast tego podano długości w treści odpowiedzi, zmieszanej z rzeczywistą treścią; nie ma sensu, aby skrypt generował oba nagłówki z góryNie znam się osobiście
chunked
, ale zgodnie z podstawowymi informacjami na stronie http://en.wikipedia.org/wiki/Chunked_transfer_encoding, a także http://tools.ietf.org/html/rfc2616#section-3.6.1 , Zgadłbym, że cała obsługa kodowania fragmentów w twoim skrypcie może być całkowicie niepoprawna.Jeśli powyższe nadal go nie obejmuje, a w rzeczywistości jest inaczej, nie jest jasne, dlaczego odpowiedź z kodem stanu
307
lub302
http powinna być wyposażona w „dziwne” kodowanie. Niedawno odbyła się podobna dyskusja na liście mailingowej nginx410 Gone
i inne strony błędów zawsze wykluczone zgzip
kompresji, i myślę, że sentyment miałby zastosowanie również tutaj. ( http://mailman.nginx.org/pipermail/nginx/2013-March/037890.html )źródło
Miałem ten sam problem ze strumieniowaniem pliku MP4 przez tag wideo HTML5.
Safari i Firefox zachowywały się normalnie, podczas gdy Chrome uruchamiał ERR_CONTENT_LENGTH_MISMATCH w pewnym momencie (ale pozwoliło mi to na obejrzenie kilku minut filmu przed niepowodzeniem).
Problem nie został odtworzony po wyłączeniu kontroli pamięci podręcznej dla plików MP4.
źródło
Udostępniając tę odpowiedź wysłałem do SO, na wypadek, gdyby była pomocna: /programming/50499637/mp4-video-safari-cloudflare-nginx-rails-no-play/59348509#59348509
Miałem podobny problem z odtwarzaniem MP4 z powodu braku obsługi fragmentów i potwierdziłem problem według przewodnika Apple'a wymienionego poniżej. Potwierdziłem, że pobierałem cały plik, a po poprawce poniżej tylko pierwszy fragment.
Rozwiązałem odtwarzanie Safari .mp4, zmieniając ustawienia kompresji gzip w pliku nginx.conf, aby usunąć kompresję gzip plików .mp4 .
Oto blok w nginx w celach informacyjnych. (Uwaga: w zależności od konfiguracji aplikacji może być konieczna zmiana linii lokalizacji na
location ~ \.mp4$ {
Odsyłacz do dokumentacji Apple: https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html#//apple_ref/doc/uid/TP465
źródło