Я использую nginx 1.2.3 для прокси к скрипту:
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8880;
proxy_buffering off;
proxy_read_timeout 300s;
gzip off;
Скрипты отправляют оба Transfer-encoding: chunked
и Content-Length: 251
:
HTTP/1.0 307 Temporary Redirect
Content-length: 251
Pragma: no-cache
Location: /...
Cache-control: no-cache
Transfer-encoding: chunked
Мне нужны оба, но nginx автоматически удаляет 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: /...
В результате клиенты не ждут отправки чанков. Раньше это работало с более ранней версией nginx.
К сожалению, я не могу комментировать сообщение cnst - поэтому отвечу здесь.
В nginx_http_proxy
модуль по умолчанию общается с восходящим потоком в HTTP / 1.0. Это можно изменить с помощью директивы proxy_http_version 1.1
.
Это также может быть причиной того, что ваш скрипт возвращает ответ HTTP / 1.0, хотя кодирование фрагментов и код состояния 307
не существует в этой версии.
Вы не должны использовать кодирование по частям с перенаправить либо, поскольку это действительно не имеет смысла.
Дополнительно, похоже, nginx не пропускает куски от восходящего потока к клиенту один за другим, но он буферизует ответ восходящего потока. В Content-Length
поле заголовка игнорируется, потому что оно противоречит определению. Я должен был посмотреть на исходный код модуля, потому что все это кажется недокументированным.
Вы можете попробовать nginx_tcp_proxy_module
для проксирования фрагментированного содержимого как необработанных данных TCP: Модуль на Github
nginx_http_proxy
module has support for X-Accel-*
заголовки, of which one (X-Accel-Buffering: yes|no
) controls whether the response should be buffered or not. Добавление этого заголовка (X-Accel-Buffering: no
) в ответ серверной части заставит nginx напрямую передавать фрагменты клиенту.
Этот заголовок позволяет управлять буферизацией на по запросу.
Модуль также имеет директива конфигурации proxy_buffering
для включения или отключения буферизации ответа (без буферизации означает, что отправка фрагментов будет работать).
Буферизация прокси (как на основе заголовков, так и директив) задокументирована. Вот.
Как сказал Лукас, HTTP 1.1 запрещает Content-Length
если есть Transfer-Encoding
устанавливать.
Цитирование http://www.ietf.org/rfc/rfc2616.txt:
3.If a Content-Length header field (section 14.13) is present, its
decimal value in OCTETs represents both the entity-length and the
transfer-length. The Content-Length header field MUST NOT be sent
if these two lengths are different (i.e., if a Transfer-Encoding
header field is present). If a message is received with both a
Transfer-Encoding header field and a Content-Length header field,
the latter MUST be ignored.
Вы конкретно не объяснили, почему вашему скрипту в первую очередь нужна фрагментированная кодировка, особенно с ответом на перенаправление.
Я вижу здесь множество проблем.
Transfer-Encoding: chunked
является HTTP/1.1
функция (и ваш скрипт, кажется, отвечает HTTP/1.0
заголовок)
здесь нет 307
в HTTP/1.0
вся цель chunked
это то, что ты не знаешь, что твое Content-Length
было бы так, chunked
используется вместо указания длины в пределах Content-Length
, где вместо этого длины указываются в теле ответа, смешанного с фактическим содержанием; было бы бессмысленно для сценария генерировать оба заголовка заранее
Я лично не знаком с chunked
, но согласно основной информации на http://en.wikipedia.org/wiki/Chunked_transfer_encoding а также http://tools.ietf.org/html/rfc2616#section-3.6.1, Я бы предположил, что вся обработка вашего скрипта фрагментированной кодировки может быть совершенно неправильной.
Если вышеупомянутое все еще не покрывает это, а на самом деле иначе, также неясно, почему ответ с 307
или 302
Код состояния http должен быть предоставлен в "странной" кодировке. Недавно в списке рассылки nginx было аналогичное обсуждение 410 Gone
и другие страницы ошибок всегда исключаются из gzip
сжатие, и я думаю, что это чувство также применимо и здесь. (http://mailman.nginx.org/pipermail/nginx/2013-March/037890.html)
У меня была такая же проблема с потоковой передачей файла mp4 через тег видео html5.
Safari и Firefox вели себя нормально, тогда как Chrome в какой-то момент запускал ERR_CONTENT_LENGTH_MISMATCH (но это позволило мне просмотреть несколько минут видео до сбоя).
Проблема не воспроизводилась после того, как я отключил управление кешем для файлов mp4.
Поделившись этим ответом, который я отправил в SO, если он будет полезен: https://stackoverflow.com/questions/50499637/mp4-video-safari-cloudflare-nginx-rails-no-play/59348509#59348509
У меня была аналогичная проблема с воспроизведением mp4 из-за того, что фрагменты не обслуживаются, и я подтвердил проблему в соответствии с руководством Apple, указанным ниже. Я подтвердил, что загружаю весь файл, а после исправления ниже только первый фрагмент.
curl --range 0-99 http://example.com/test.mov -o /dev/null
Я разрешил воспроизведение файлов Safari .mp4, изменив настройки сжатия gzip в моем nginx.conf, чтобы удалить сжатие gzip для .mp4 файлы.
Вот блок в nginx для справки. (Примечание: в зависимости от того, как настроено ваше приложение, вам может потребоваться изменить строку местоположения на location ~ \.mp4$ {
location ~ ^/(assets|system|videos)/ {
expires max;
add_header Cache-Control public;
add_header ETag "";
gzip on;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 6;
gzip_proxied any;
# Reference configuration
#gzip_types text/plain text/html text/css application/json application/javascript application/x-javascript text/javascript video/mp4 application/mp4 image/jpeg image/png image/svg+xml application/x-font-ttf application/x-font-truetype application/font-woff application/font-woff2 application/vnd.ms-fontobject;
# Kelton trying to fix cloudflare by removing the mp4 settings
gzip_types text/plain text/html text/css application/json application/javascript application/x-javascript text/javascript image/jpeg image/png image/svg+xml application/application/x-font-ttf application/x-font-truetype application/font-woff application/font-woff2 application/vnd.ms-fontobject;
}
Ссылка на справочную документацию Apple: https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html#//apple_ref/doc/uid/TP40006514-SW6