Фрагментарное HTTP-кодирование. Нужен пример «Трейлера», упомянутого в SPEC

Я пишу парсер HTTP для прозрачного прокси. Что меня ставит в тупик, так это Trailer:, упомянутое в спецификациях для Transfer-Encoding: chunked. На что это похоже?

Обычно HTTP-фрагмент заканчивается так.

0\r\n
\r\n

Что меня смущает, так это то, как определить конец фрагмента, если есть какие-то конечные заголовки...

ОБНОВЛЕНИЕ: я считаю, что простого \r\n\r\n, т. е. пустой строки, достаточно, чтобы определить конец конечных заголовков... Это правильно?


person unixman83    schedule 08.04.2011    source источник
comment
Спасибо за публикацию этого, я задавался тем же вопросом. Что меня сбивало с толку, так это то, что фрагмент нулевой длины не имеет собственного \r\n после данных нулевой длины. Теперь ясно, что я перечитал RFC еще раз, но приятно видеть четкий пример того, как это выглядит с каким-то заголовком... хотелось бы, чтобы они добавили это в RFC.   -  person eselk    schedule 23.03.2012
comment
Итак... как вы обнаруживаете фрагментированные части из потока с кодировкой Gzip?   -  person Alexsandro    schedule 20.06.2012
comment
@Alexsandro_xpt - тело сообщения сначала сжимается, а затем разбивается на фрагменты, так что вы можете декодировать кодировку фрагмента, ничего не распаковывая. tools.ietf.org/html/rfc7230#section-3.3.1   -  person Hawkeye Parker    schedule 03.09.2014


Ответы (3)


Ниже приведена копия примера трейлера, который я скопировал с сайта TCP/IP Guide. . пример трейлера

Как мы видим, если мы хотим использовать заголовок трейлера, нам нужно добавить поле заголовка «Trailer:header_name» с именем заголовка, а затем добавить объект заголовка трейлера после фрагментированной области тела.

Мы можем добавить 0 или более заголовков трейлеров в тело HTTP в соответствии с RFC. Раздел 4.1.2 RFC7230 запрещает использование следующих заголовков в конце заголовка. область:

Отправитель НЕ ДОЛЖЕН генерировать трейлер, который содержит поле, необходимое для кадрирования сообщения (например, Transfer-Encoding и Content-Length), маршрутизации (например, Host), модификаторов запроса (например, элементы управления и условия в разделе 5 RFC7231), аутентификация (например, см. RFC7235 и RFC6265), данные управления ответом ( например, см. раздел 7.1 RFC7231), или определение того, как обрабатывать полезную нагрузку (например, Content- Кодирование, Content-Type, Content-Range и Trailer).

Это означает, что мы можем использовать другие стандартные заголовки и пользовательские заголовки в области заголовка трейлера.

person appleleaf    schedule 21.07.2014
comment
Верно, но вам действительно следует процитировать RFC 7230. - person Julian Reschke; 21.07.2014
comment
Спасибо за комментарий, Юлиан. Я только что просмотрел RFC 7230 и обновил свою цитату. Для кусковой и концевой части это более понятно. - person appleleaf; 22.07.2014
comment
Хороший пример, но у него неправильные значения длины чанков. Фиксированные фрагменты: 28 <html><body><p>The file you requested is и 21 bytes long and was last modified: - person slinkin; 17.02.2021

0\r\n
SomeAfterHeader: TheData \r\n
\r\n

Другими словами, достаточно найти \r\n\r\n, говоря простым языком: пустую строку. Чтобы обнаружить конец передачи, разделенной на фрагменты. Но очень важно, чтобы каждый фрагмент был прочитан, прежде чем делать это. Поскольку сами данные, разбитые на фрагменты, могут содержать пустые строки, которые ошибочно будут обнаружены как конец потока.

person unixman83    schedule 15.04.2011
comment
... достаточно найти \r\n\r\n, говоря простым языком: пустую строку. Чтобы обнаружить конец передачи, разделенной на фрагменты. Это кажется мне неправильным. ABNF очень понятен: вы должны читать данные блока в соответствии с блоком -размер; когда вы обнаружите, что находите фрагмент размером 0, вы нашли последний фрагмент. Остальная часть вашего ответа превосходна, но я думаю, вам следует исправить это предложение. - person Hawkeye Parker; 03.09.2014
comment
@ unixman83: Если ваш ответ неверен (как указал Соколиный Глаз Паркер), вы должны либо исправить его, либо снять отметку как принятый ответ. Не вводите в заблуждение пользователей SO. Многие люди, в том числе и я, принимают ТАК ответы как должное, не читая все комментарии, потому что часто они заслуживают доверия. Кажется, это исключение, которое посетители должны поймать!! - person M-D; 12.05.2016

Относительно трейлера:

Как вы заметили, список конечных заголовков должен быть указан в заголовке Trailer.

BNF в Раздел 14.40 RFC 2616 выглядит следующим образом:

Trailer  = "Trailer" ":" 1#field-name

Гурли и Тотти приводят такой пример:

Trailer: Content-Length

(Странно, что они приводят этот пример, поскольку Content-Length явно запрещено быть конечным заголовком в 14.40.)

Шифлетт приводит такой пример:

Trailer: Date

Что касается конца сообщения с завершающими заголовками:

BNF в разделе 3.6.1 RFC 2616 — это то, что вы находясь в поиске. Вот часть:

Chunked-Body = *chunk
               last-chunk
               trailer
               CRLF
last-chunk   = 1*("0") [ chunk-extension ] CRLF
trailer      = *(entity-header CRLF)

Таким образом, последний фрагмент и 2 завершающих заголовка могут выглядеть так:

0<CRLF>
Date:Sun, 06 Nov 1994 08:49:37 GMT<CRLF>
Content-MD5:1B2M2Y8AsgTpgAmY7PhCfg==<CRLF>
<CRLF>
person james.garriss    schedule 03.07.2012
comment
С какой стати люди приводят примеры, которые только демонстрируют простые случаи???? Что делать, если в трейлерах несколько заголовков? Вы используете список через запятую или как? - person developerbmw; 08.11.2014
comment
С какой стати люди не удосуживаются прочитать спецификацию для себя???? Ответ на ваш вопрос уже есть в моем ответе. Хотите подсказку? Это поле 1#. Хотите еще? Перейдите сюда: tools.ietf.org/html/rfc2616#section-2.1 . - person james.garriss; 08.11.2014