Буферизация вывода и протокол HTTP

korpus

злой бобёр
Буферизация вывода и протокол HTTP

Меня заинтересовал такой вопрос. По протоколу HTTP при отправке страницы клиенту должен указываться заголовок Content-Length, указывающий количество битов, передаваемых в теле ответа. При буферизации же контент отдаётся в браузер порциями.
Как тогда выглядят HTTP заголовки ответа сервера? Сервер же не знает, сколько данных будет затем отправлено? Какой Content-Length он ставит в этом случае?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
никакого
количество _байтов_
если речь о чанке - то сервер сначала буферизует данные, потом отдает, и уже знает, сколько их в чанке
 

LONGMAN

Dark Side of the Moon..
Ragazzo
Посмотри заголовки с сервера и ищи Transfer-Encoding: chunked
 

fixxxer

К.О.
Партнер клуба
Между прочим, это очень хороший вопрос.

В HTTP/1.0 Content-Length был совершенно необязателен - там на один запрос одно соединение. Нет Content-Length - значит, до опупения, то есть пока соединение не закрыто.

В HTTP/1.1 появился keep-alive, и тут возникла проблема, что делать, если Content-Length узнать невозможно. Обязать все бэкенды считать Content-Length и лишиться возможности отдавать поток "как есть" - плохая идея. Но когда закончилась передача ответа на данный запрос, и можно переходить к следующему, надо знать, иначе какой-то keep alive неправильный получается. Для этого придумали transfer-encoding: chunked, который помимо прочего прекрасно ложился на существующие архитектуры веб-серверов (в широком смысле). Вот есть буфер, отдаем его длину и содержимое (то есть чанк), и так по кругу, как поток закончился - отдаем нулевой чанк (длина 0).

Кстати, то, что php-прогромизды не понимают, что они пишут, часто выходит боком. Есть известный прикол со схемой nginx-apache+mod_php и всяким говнокодом вида <? header('HTTP/1.1 404 Not found'); readfile('404.tpl'); ?>. Nginx работает с бэкендом только по протоколу http/1.0 (почему так - отдельный вопрос, не суть). Заголовок с ответом 1.1 же "переключает" апач в работу по протоколу 1.1, и он честно отдает этот самый 404.tpl в chunked transfer encoding (а что ему еще делать если content-length никто не сказал?). Nginx же это дело забирает, ожидая ответа по 1.0 (а почему он должен ждать чего то еще если сделал запрос по 1.0?), и честно отдает все клиенту вместе с длинами чанков. А потом эти придурки бегут на форумы и спрашивают что за непонятные байты внезапно вылезли на хостинге и орут что хостинг дерьмо, ведь на денвере у них все работает. :D
 

korpus

злой бобёр
Автор оригинала: fixxxer
А потом эти придурки бегут на форумы и спрашивают что за непонятные байты внезапно вылезли на хостинге и орут что хостинг дерьмо, ведь на денвере у них все работает. :D
Ну... это про меня сказано :)

-~{}~ 16.08.10 18:07:

fixxxer, пересказывать RFC необязательно. Можно просто дать ссылку или указать в каком конкретно стандарте можно ответ найти
 

fixxxer

К.О.
Партнер клуба
Да ни хрена там никто не понимает, думаешь не давал?

Я ваще писал чтобы потом сюда ссылки давать )
 

korpus

злой бобёр
fixxxer, спасибо, конечно, что помогаете в моём вопросе. Но мне надо советы давать с учётом того, что я начинающий и ещё много чего не понимаю.
 

fixxxer

К.О.
Партнер клуба
чо ты хочешь то от меня я не понимаю)))

rfc 2616 ^f chunked
 

korpus

злой бобёр
Сам отвечу на свой же вопрос. Про Content-Length подробно говорит раздел 4.4 стандарта RFC2616. Там и про chuncked можно найти и даже почитать про него.

Небольшой вопрос. В каком смысле в RFC2616 в разделе 4.4. употребляется слово "entity" и слова на его основе: "entity-lenght", "entity-header"? А так же рядом употребляются слова "message" и "message-lenght"?
 

fixxxer

К.О.
Партнер клуба
The transfer-length of a message is the length of the message-body as
it appears in the message; that is, after any transfer-codings have
been applied
.

The entity-length of a message is the length of the message-body
before any transfer-codings have been applied.
 
Сверху