HTTP сообщение. Типы сообщений

Сообщения HTTP включают в себя запросы клиента к серверу и отклики сервера клиенту.

HTTPmessage = Request | Response ; HTTP/1.1 messages

Сообщения запрос и отклик используют общий формат сообщений RFC-822 [7.9] для передачи объектов (поле данных сообщения). Оба типа сообщений состоят из стартовой строки, одного или более полей заголовка (также известные как "заголовки"), пустой строки (то есть, строка, содержащая CRLF ), отмечающей конец полей заголовка, а также опционного тела сообщения.

genericmessage = startline
*messageheader
CRLF
[ messagebody ]
startline = RequestLine | StatusLine

В интересах надежности рекомендуется серверам игнорировать любые пустые строки, полученные, когда ожидается RequestLine (строка запроса). Другими словами, если сервер читает протокольный поток в начале сообщения и получает сначала CRLF, он должен игнорировать CRLF.

Определенные некорректные реализации HTTP/1.0 клиентов генерируют дополнительные CRLF после запроса POST. Клиент HTTP/1.1 не должен посылать CRLF до или после запроса.

Заголовки сообщений

Поля заголовка HTTP, которые включают в себя общие поля заголовка, заголовка запроса, заголовка отклика и заголовка объекта, следуют тому же общему формату, что дан в разделе 3.1 RFC-822 [7.9]. Каждое поле заголовка состоит из имени, за которым следует двоеточие (":"), и поля значения. Поля имен безразличны в отношении использования строчных и прописных букв. Поле значения может начинаться с любого числа LWS, хотя один SP предпочтительнее. Поля заголовка могут занимать несколько строк, каждая новая строка должна открываться, по крайней мере, одним SP или HT. Рекомендуется, чтобы приложения следовали общему формату, если они создаются конструкциями HTTP, так как могут существовать некоторые реализации, которые не могут воспринимать ничего, кроме общих форматов.

Messageheader = fieldname ":" [ fieldvalue ] CRLF
fieldname = token
fieldvalue = *( fieldcontent | LWS )

fieldcontent = <OCTET'ы образуют значения поля и состоят из *TEXT или комбинаций лексем, tspecials и закавыченных строк>

Порядок, в котором приходят поля заголовка с отличающимися именами, не имеет значения. Однако хорошей практикой считается посылка сначала поля общего заголовка, за которым следует заголовок запроса или отклика, а в заключение поля заголовка объекта.

Множественные поля заголовка сообщения с идентичными именами могут присутствовать тогда и только тогда, когда значение поля определяется как список из элементов, разделенных запятыми [то есть, #(значения)]. Должна быть предусмотрена возможность объединять множественные поля заголовка в одну пару "имя_поля: значение_поля", без изменения семантики сообщения, путем добавления каждой последующей пары полезначение, отделенных друг от друга запятыми. Порядок, в котором следуют поля заголовка с идентичными именами, влияет на последующую интерпретацию значения комбинированного поля, по этой причине проксисервер не должен менять порядок значений этих полей при переадресации сообщения.

го длина определяется следующим образом (в порядке приоритета).

1. Любое сообщение­отклик, которое не должно включать в себя тело сообщения (такое, как отклик 1xx, 204 и 304, а также любые отклики на запрос HEAD), всегда завершаются первой пустой строкой после полей заголовка, вне зависимости от присутствующих в сообщении полей заголовка объекта.

2. Если присутствует поле заголовка Transfer-Encoding и указано, что использовано фрагментное ("chunked") транспортное кодирование, тогда длина тела определяется выбранной схемой кодирования.

3. Если присутствует поле заголовка ContentLength, его значение в байтах и определяет длину тела сообщения.

4. Если сообщение использует тип cреды multipart/byteranges, который является самоограничивающим, тогда он и определяет длину. Этот тип среды не должен использоваться, если отправитель не знает, может ли получатель разобрать его. Присутствие в запросе заголовка Range с множественными спецификаторами диапазона подразумевает, что клиент может разобрать отклики типа multipart/byteranges.

5. Длина определяется сервером при закрытии связи. (Закрытие соединения не может применяться для обозначения конца тела запроса, так как это не оставит возможности для сервера послать отклик.)

Для совместимости с приложениями HTTP/1.0, запросы HTTP/1.1, содержащие тело запроса, должны включать корректное поле заголовка ContentLength. Когда запрос содержит тело сообщения, а поле ContentLength отсутствует, рекомендуется, чтобы сервер реагировал откликом 400 (плохой запрос), если он не может определить длину сообщения, или 411 (необходима длина), если он настаивает на получении корректного поля ContentLength.

Все приложения HTTP/1.1, которые получают объект ( entity ), должны понимать блочное ( chunked ) транспортное кодирование, таким образом, разрешая использование этого механизма для сообщений, когда длина сообщения не может быть определена заранее.

Сообщения не должны включать поле заголовка ContentLength и блочное транспортное кодирование одновременно. Если такое сообщение получено, поле ContentLength должно игнорироваться.

Когда в сообщении присутствует поле ContentLength и разрешено наличие тела сообщения, его значение поля должно строго соответствовать числу октетов в теле сообщения. Агенты пользователя HTTP/1.1 должны оповещать пользователя, если получено сообщение некорректной длины.

Общие поля заголовка

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

generalheader = Cache-Control
| Connection
| Date
| Pragma
| Transfer-Encoding
| Upgrade
| Via

Имена полей общего заголовка могут быть расширены только при изменении версии протокола. Однако новые или экспериментальные поля заголовка могут использоваться при условии, если партнеры обмена способны их распознавать как поля общего заголовка. Неузнанные поля заголовка считаются полями заголовка объекта ( entity ).

Запрос

Сообщениезапрос от клиента к серверу включает в себя, в пределах первой строки сообщения, метод, который должен быть использован для ресурса, идентификатор ресурса и код версии используемого протокола.

Request = RequestLine
*( generalheader
| requestheader
| entityheader )
CRLF
[ messagebody ]

Строка запроса

Строка запроса начинается с лексемы метода, за которой следует Request-URI, версия протокола, и завершается строка последовательностью CRLF. Элементы разделяются символами SP. Символы CR или LF запрещены, кроме завершающей последовательности CRLF.

Request Line = Method SP Request-URI SP HTTPVersion CRLF

Метод

Лексема Method указывает на метод, который должен быть применен к ресурсу, обозначенному Request-URI. При записи метода использование строчных или прописных букв не безразлично.

Method = "OPTIONS"
| "GET"
| "HEAD"
| "POST"
| "PUT"
| "DELETE"
| "TRACE"
| extensionmethod extensionmethod = token

Список методов, допустимых для ресурса, может быть специфицирован полем заголовка Allow. Возвращаемый код отклика всегда оповещает клиента, допустим ли метод для ресурса, так как набор допустимых методов может меняться динамически. Серверам рекомендуется возвращать статусный код 405 (Метод не допустим), если метод известен серверу, но не приемлем для запрашиваемого ресурса, и 501 (Не применим), если метод не узнан или не приемлем для сервера. Список методов, известных серверу, может быть представлен в поле заголовка отклика Public.

Методы GET и HEAD должны поддерживаться всеми серверами общего назначения.

URI запроса

URI запроса является универсальным идентификатором ресурса и идентифицирует ресурс, который запрашивается.

Request-URI = "*" | absoluteURI | abs_path

Три опции для Request-URI зависят от природы запроса. Звездочка "*" означает, что запрос приложим не к заданному ресурсу, но к самому серверу, и допустим только, когда используемый метод не обязательно приложим к ресурсу. Примером может служить

OPTIONS * HTTP/1.1

Форма абсолютного URI необходима, когда запрос адресован к проксисерверу. Прокси­серверу посылается запрос переадресации с целью получения отклика. Заметьте, что прокси может переадресовать запрос другому прокси или серверу, указанному абсолютным URI. Чтобы избежать петель запросов, проксисервер должен быть способен распознавать все имена серверов, включая любые псевдонимы, локальные вариации и численные IP-адреса. Пример строки запроса представлен ниже:

GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1

Для того чтобы разрешить передачу абсолютных URI в запросах будущих версий HTTP, все серверы HTTP/1.1 должны уметь работать с запросами абсолютных форм URI.

Наиболее общей формой Request-URI является та, которая используется для идентификации ресурса на исходном сервере или внешнем порту сети. В этом случае абсолютный проход к URI должен быть занесен в abs_path как Request-URI, а сетевой адрес URI (net_loc) должен быть занесен в поле заголовка Host. Например, клиент, желающий извлечь ресурс из выше приведенного примера непосредственно с базового сервера, установит TCP-соединение через порт 80 с ЭВМ www.w3.org и пошлет строки:

GET /pub/WWW/TheProject.html HTTP/1.1
Host: www.w3.org

за которыми следует остальная часть запроса. Заметьте, что абсолютный проход не может быть пустым; если его нет в исходном URI, он должен быть задан в виде "/" (корневой каталог сервера).

Если прокси получает запрос без какого-либо прохода в Request-URI, а метод специфицирован так, чтобы быть способным поддерживать форму "*" запросов, тогда последний прокси в цепочке запроса должен переадресовать запрос со "*" в качестве финального Request-URI. Например, запрос

OPTIONS http://www.ics.uci.edu:8001 HTTP/1.1

будет переадресован прокси как

OPTIONS * HTTP/1.1
Host: www.ics.uci.edu:8001

после подключения к порту 8001 ЭВМ www.ics.uci.edu.

Исходный сервер должен декодировать Request-URI, чтобы правильно интерпретировать запрос. Серверам рекомендуется откликаться на некорректный запрос Request-URI, соответствующим статусным кодом.

В запросах, которые они переадресуют, проксисерверы не должны переписывать abs_path -часть Request-URI каким­-либо способом, за исключением случая, описанного выше, когда нулевой abs_path заменяется на "*".

Правило "no rewrite" препятствует прокси изменить смысл запроса, когда исходный сервер некорректно использует незарезервированный URL символ для зарезервированных целей.

Следует остерегаться ситуации, когда некоторые предшествующие варианты проксисерверов HTTP/1.1 допускают перезапись Request-URI.

Наши рекомендации