Как я могу отключить Transfer-Encoding: chunked в Apache с ответами HTTP/1.1

У меня есть страница mod_include (SSI), которая генерирует ошибочный вывод во время кодирования по частям, когда запрашивается браузером HTTP/1.1.

Страница выводится нормально при запросе HTTP/1.0 (потому что вывод не разделен на части).

Как я могу сказать Apache не использовать чанкованную кодировку по запросу браузера HTTP/1.1?

Дополнительная информация: ошибочный порционный вывод вызван включенной поддержкой sendfile() на машине Solaris 5.10 с процессором sparc. Отключение поддержки sendfile() приводит к исчезновению этой проблемы; Однако я пытаюсь поймать эту ошибку и исправить ее.

3 ответа

Решение

Если вы предварительно укажете Content-length, Apache не придется использовать chunked. Без Content-length у Apache нет другого выбора, кроме как использовать его.

Для ясности: HTTP/1.0 управляет им, потому что Apache читает весь ответ перед отправкой, поэтому он знает, насколько большим он будет. Это крайне неэффективно и медленно, и AFAIK нет способа включить эту логику для запросов HTTP/1.1, кроме как принудительно заставить их HTTP/1.0 (что вы действительно, действительно не хотите делать, не так ли? Если вы делаете, переменная окружения для установки - "downgrade-1.0")

Приведенный выше ответ неверен.

Если запрос HTTP/1.0, Apache никогда не буферизует ответ перед отправкой (с заголовком Content-Length). Конечно, Apache может сделать это, но есть более элегантное решение, которое использует Apache: он отвечает заголовком "Connection: close" и закрывает соединение, как только отправляет все данные.

Согласно спецификации HTTP, наличие заголовка "Connection: close" означает, что клиент должен читать, пока соединение не будет закрыто.

Решение вашей проблемы - заставить Apache обработать запрос как HTTP / 1.0, установив упомянутую переменную среды downgrade-1.0. Кодированное Transfer-Encoding - это функция HTTP/1.1, и Apache не будет использовать ее для запроса HTTP / 1.0.

Например, вот как вы можете отключить фрагментированные ответы для файлов php:

++++++++++++
apache.conf
++++++++++++

<Files *.php>
    SetEnv downgrade-1.0
</Files>

Клиент Apache попытается определить размер отправляемого тела. Предварительное указание "Content-Length" приведет к ошибке, если вы не используете специальные перехватчики.

Он проверяет сущность, которую он будет отправлять, чтобы определить, является ли он фрагментированным или имеет размер тела (content-length) < 0, и если любой из них равен true, тогда он использует заголовок "Transfer-Encoding=chunked". Если объект не предпочитает фрагментирование и найдена длина контента> -1, тогда он использует заголовок "Content-Length".

Обычно, если источником тела является часть тела MIME, он будет использовать "Transfer-Encoding", потому что вызов метода size() возвращает -1, поэтому преобразование части тела MIME в байтовый массив будет работать, так как он вернет число байтов в массиве.

У меня были похожие проблемы. Решил проблему, убрав Transfer-encoding заголовок из ответа прямо в приложении.

Другие вопросы по тегам