LINUX.ORG.RU

[СИ] HTTP/1.1. Chunked


0

1

[СИ] HTTP/1.1. Chunked

Язык СИ
ОС UNIX

Помогите разобраться.

Вот выдержки из rfc2616
http://www.ietf.org/rfc/rfc2616

Пункт 3.6.1
       Chunked-Body   = *chunk
                        last-chunk
                        trailer
                        CRLF

       chunk          = chunk-size [ chunk-extension ] CRLF
                        chunk-data CRLF
       chunk-size     = 1*HEX
       last-chunk     = 1*("0") [ chunk-extension ] CRLF

       chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
       chunk-ext-name = token
       chunk-ext-val  = token | quoted-string
       chunk-data     = chunk-size(OCTET)
       trailer        = *(entity-header CRLF)

----------------------------------------------

Пункт 7.1

       entity-header  = Allow                    ; Section 14.7
                      | Content-Encoding         ; Section 14.11
                      | Content-Language         ; Section 14.12
                      | Content-Length           ; Section 14.13
                      | Content-Location         ; Section 14.14
                      | Content-MD5              ; Section 14.15
                      | Content-Range            ; Section 14.16
                      | Content-Type             ; Section 14.17
                      | Expires                  ; Section 14.21
                      | Last-Modified            ; Section 14.29
                      | extension-header

       extension-header = message-header

----------------------------------------------

Пункт 4.2

       message-header = field-name ":" [ field-value ]
       field-name     = token
       field-value    = *( field-content | LWS )
       field-content  = <the OCTETs making up the field-value
                        and consisting of either *TEXT or combinations
                        of token, separators, and quoted-string>

Пытаюсь написать простой HTTP-клиент.
Для написания и теста парсеров заголовков нужны «максимальные» заголовки,
т. е. наиболее неудобные для парсения.
А получаю только «минимальные», простецкие.
Вот сам написал для теста файл.

HTTP/1.1 200 OK
Set-Cookie: yandexuid=1140701277744450; path=/; domain=.yandex.ru
X-Robot-status: off
transfer-encoding: chunked
Content-Type:
	text/html;
	charset=windows-1251
My-Var: Proba

8
data-1 ;
 8; eda=kolbasa
data-2 ;
8
data-3 ;
0; file=nul
name1:  id64;
	id65
name2:
	id76
	konec

В конце пустая строка («\r\n\r\n»).
Чистое тело «data-1 ;data-2 ;data-3 ;»

Вопрос-1.
Правильно ли я понял, что заголовок блока данных (chunked) всегда
одна-единственная строка, и, значит, перенос строки - это верный признак
конца заголовка блока. Как в примере:
" 8; eda=kolbasa"
«0; file=nul»

Вопрос-2.
Правильно ли я понял, что последний нулевой блок может содержать
завершающую запись (trailer), которая подобна обычному верхнему
HTTP-заголовку (а не что-нибудь другое), и, значит, парсить ее
нужно подобным способом?

Кто знает прошу ответить.


Ответ на: комментарий от Eddy_Em

Eddy_Em
Спасибо за отклик.
Но нет, не то.

Парсеры для клиента у меня сделаны.
Они могут принять страницу, как в моем примере.
Парсеров два. Один для HTTP-заголовка, другой
для заголовков блоков.
Тот, который для блоков, он простой, выпарсивает только
индикаторы длины, отделяет сами данные, и находит конец всей посылки.
Но прокручивать-то он должен всё, что есть кроме данных.

Проще говоря, сейчас малый парсер (для блоков) все заголовки, кроме
нулевого, прокручивает до первого переноса, дальше начинаются данные.
А нулевой блок прокручивает до двойного переноса. Это конец.
Якобы это должно работать. Если я правильно понял. И работает. Keep-Alive.
Но вдруг придет заголовок такого вида, о котором я не знаю.
Поэтому и вопрос возник.

oleg_2 ()

1. Дa

2. Дa и нет. Дополнительные поля идут за последним нулевым чанком (не являются её частью). Список дополнительных полей должен быть указан в поле Trailer основного заголовка, см. пункт 14.40

mashina ★★★★★ ()
Ответ на: комментарий от anonymous

anonymous
Нет.

Eddy_Em
Хоть это не относится к теме, но
увидел в Вашем примере незнакомую конструкцию
в файле «query.c»:

int get_qs_param(char *qs, char *param, char *meaning, int l){
char *tok, *val, *par, str[l+1];

Конкретнее:

int get_qs_param(... , int l){
char ... , str[l+1];

Что это? Ошибка, или так можно делать?
Как я понимаю, память выделяется локально в стеке в момент вызова
функции. В это время l известно, и в принципе не противоречиво.
Но я этого не знал. Поясните.

oleg_2 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.