Ich verwende Nginx 1.2.3 als Proxy für ein Skript:
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8880;
proxy_buffering off;
proxy_read_timeout 300s;
gzip off;
Die Skripte senden beide Transfer-encoding: chunked
und Content-Length: 251
:
HTTP/1.0 307 Temporary Redirect
Content-length: 251
Pragma: no-cache
Location: /...
Cache-control: no-cache
Transfer-encoding: chunked
Ich brauche beides, aber nginx entfernt automatisch das 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: /...
Infolgedessen warten die Clients nicht auf das Senden der Chunks. Dies funktionierte früher mit einer früheren Version von Nginx.
Antworten:
Leider kann ich den Beitrag von cnst nicht kommentieren - daher werde ich hier antworten.
Das
nginx_http_proxy
Modul kommuniziert standardmäßig mit dem Upstream in HTTP / 1.0. Dies kann mit der Richtlinie geändert werdenproxy_http_version 1.1
.Dies kann auch die Ursache dafür sein, dass Ihr Skript eine HTTP / 1.0-Antwort zurückgibt, obwohl Chunked Coding und Statuscode
307
in dieser Version nicht vorhanden sind.Sie sollten auch keine Blockcodierung mit einer Umleitung verwenden , da dies nicht wirklich sinnvoll ist.
Darüber hinaus scheint es so, als ob Nginx keine Chunks vom Upstream einzeln an den Client weiterleitet, sondern die Antwort des Upstreams puffert . Das
Content-Length
Header-Feld wird ignoriert, da es gegen die Definition verstößt. Ich musste mir den Quellcode des Moduls ansehen, da dies alles undokumentiert zu sein scheint.Möglicherweise möchten Sie versuchen, den
nginx_tcp_proxy_module
Chunk-Inhalt als TCP-Rohdaten zu vertreten: Modul bei GithubUPDATE (10.04.14)
Das
nginx_http_proxy
Modul unterstütztX-Accel-*
Header , von denen one (X-Accel-Buffering: yes|no
) steuert, ob die Antwort gepuffert werden soll oder nicht.Wenn Sie diesen Header (
X-Accel-Buffering: no
) zur Antwort des Backends hinzufügen, übergibt nginx Chunks direkt an den Client.Dieser Header ermöglicht die Steuerung der Pufferung pro Anforderung .
Das Modul verfügt außerdem über eine Konfigurationsanweisung
proxy_buffering
zum Aktivieren oder Deaktivieren der Antwortpufferung (keine Pufferung bedeutet, dass das Senden von Chunks funktioniert).Die Proxy-Pufferung (sowohl auf Header- als auch auf Direktivenbasis) ist hier dokumentiert .
quelle
nginx_tcp_proxy_module
. Es funktioniert nur mit einigen Browsern, weil sie sehr fehlertolerant sind.Wie Lukas anspielt, verbietet HTTP 1.1,
Content-Length
wenn es einenTransfer-Encoding
Satz gibt.Zitat http://www.ietf.org/rfc/rfc2616.txt :
quelle
Sie haben nicht speziell erläutert, warum Ihr Skript überhaupt eine Chunk-Codierung benötigt, insbesondere mit einer Umleitungsantwort.
Ich sehe hier eine Vielzahl von Problemen.
Transfer-Encoding: chunked
ist eineHTTP/1.1
Funktion (und Ihr Skript scheint mit einemHTTP/1.0
Header zu antworten )es gibt kein
307
inHTTP/1.0
Der ganze Zweck von
chunked
ist, dass Sie nicht wissen, was Ihre gewesenContent-Length
wäre, alsochunked
wird anstelle der Angabe der Länge innerhalb verwendetContent-Length
, wobei stattdessen Längen innerhalb des Hauptteils der Antwort angegeben werden, vermischt mit dem tatsächlichen Inhalt; Es wäre sinnlos, wenn ein Skript beide Header im Voraus generieren würdeIch bin nicht persönlich vertraut
chunked
, aber gemäß den grundlegenden Informationen unter http://en.wikipedia.org/wiki/Chunked_transfer_encoding und auch http://tools.ietf.org/html/rfc2616#section-3.6.1 , Ich würde schätzen, dass die gesamte Handhabung der Chunk-Codierung durch Ihr Skript möglicherweise völlig falsch ist.Wenn das oben Gesagte es immer noch nicht abdeckt, und in Wirklichkeit auch sonst, ist es auch unklar, warum eine Antwort mit einem
307
oder302
http-Statuscode mit einer "seltsamen" Codierung versehen werden sollte. Es gab kürzlich eine ähnliche Diskussion in der Nginx-Mailingliste über410 Gone
und andere Fehlerseiten, die immer von dergzip
Komprimierung ausgeschlossen waren , und ich denke, das Gefühl würde hier gleichermaßen gelten. ( http://mailman.nginx.org/pipermail/nginx/2013-March/037890.html )quelle
Ich hatte das gleiche Problem beim Streamen von MP4-Dateien über HTML5-Video-Tags.
Safari und Firefox verhielten sich normal, während Chrome irgendwann ERR_CONTENT_LENGTH_MISMATCH auslöste (aber es erlaubte mir, einige Minuten des Videos zu sehen, bevor es fehlschlug).
Das Problem wurde nicht reproduziert, nachdem ich die Cache-Steuerung für MP4-Dateien deaktiviert hatte.
quelle
Diese Antwort habe ich an SO gesendet, falls sie hilfreich ist: /programming/50499637/mp4-video-safari-cloudflare-nginx-rails-no-play/59348509#59348509
Ich hatte ein ähnliches Problem mit der MP4-Wiedergabe, da Chunks nicht bereitgestellt wurden, und bestätigte das Problem gemäß dem unten aufgeführten Apple-Handbuch. Ich habe überprüft, ob ich die gesamte Datei heruntergeladen habe, und nach dem folgenden Fix nur den ersten Block.
Ich habe meine Safari .mp4-Wiedergabe aufgelöst, indem ich meine Einstellungen für die gzip-Komprimierung in meiner nginx.conf geändert habe, um die gzip-Komprimierung von .mp4- Dateien zu entfernen .
Hier ist der Block in Nginx als Referenz. (Hinweis: Je nachdem, wie Ihre App konfiguriert ist, müssen Sie möglicherweise die Standortzeile in ändern
location ~ \.mp4$ {
Link zur Apple-Dokumentationsreferenz: https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html#//apple_ref/doc/uid/
quelle