N/RFCNET
← Карточка документаEnglish original ↗

RFC 9112 · STD 99 · Июнь 2022

HTTP/1.1

Internet Engineering Task Force (IETF)
R. Fielding, редактор, Adobe
M. Nottingham, редактор, Fastly
J. Reschke, редактор, greenbytes
Заменяет: RFC 7230
Категория: Standards Track
ISSN: 2070-1721

Аннотация

Протокол передачи гипертекста (HTTP) — это не сохраняющий состояние протокол прикладного уровня для распределённых гипертекстовых информационных систем с совместным доступом. Настоящий документ определяет синтаксис сообщений HTTP/1.1, разбор сообщений, управление соединениями и связанные с этим вопросы безопасности.

Настоящий документ заменяет части RFC 7230.

Статус документа

Это документ процесса стандартизации Интернета.

Этот документ подготовлен Internet Engineering Task Force (IETF). Он отражает консенсус сообщества IETF. Документ прошёл открытое рассмотрение и был утверждён к публикации Internet Engineering Steering Group (IESG). Дополнительные сведения об интернет-стандартах приведены в разделе 2 RFC 7841.

Сведения о текущем статусе этого документа, обнаруженных в нём ошибках и способах отправки отзывов можно получить по адресу https://www.rfc-editor.org/info/rfc9112.

Уведомление об авторских правах

Copyright © 2022 IETF Trust и лица, указанные как авторы документа. Все права защищены.

На этот документ распространяются BCP 78 и правовые положения IETF Trust, относящиеся к документам IETF (https://trustee.ietf.org/license-info), действовавшие на дату публикации документа. Внимательно ознакомьтесь с этими документами: они описывают ваши права и ограничения в отношении этого документа. Компоненты кода, извлечённые из этого документа, должны включать текст Revised BSD License, как описано в разделе 4.e правовых положений Trust, и предоставляются без гарантий, как описано в Revised BSD License.

Этот документ может содержать материалы из документов или вкладов IETF, опубликованных или ставших общедоступными до 10 ноября 2008 года. Лица, контролирующие авторские права на некоторые из этих материалов, могли не предоставить IETF Trust право разрешать изменение таких материалов вне процесса стандартизации IETF. Без получения соответствующей лицензии у лиц, контролирующих авторские права на такие материалы, этот документ нельзя изменять вне процесса стандартизации IETF и создавать на его основе производные работы вне этого процесса, за исключением форматирования для публикации в качестве RFC или перевода на языки, отличные от английского.

Содержание

1. Введение
  1.1. Обозначение требований
  1.2. Обозначения синтаксиса
2. Сообщение
  2.1. Формат сообщения
  2.2. Разбор сообщения
  2.3. Версия HTTP
3. Строка запроса
  3.1. Метод
  3.2. Цель запроса
    3.2.1. origin-form
    3.2.2. absolute-form
    3.2.3. authority-form
    3.2.4. asterisk-form
  3.3. Восстановление целевого URI
4. Строка состояния
5. Синтаксис полей
  5.1. Разбор строки поля
  5.2. Устаревший перенос строк
6. Тело сообщения
  6.1. Transfer-Encoding
  6.2. Content-Length
  6.3. Длина тела сообщения
7. Кодирования передачи
  7.1. Кодирование передачи chunked
    7.1.1. Расширения частей
    7.1.2. Секция трейлера chunked
    7.1.3. Декодирование chunked
  7.2. Кодирования передачи для сжатия
  7.3. Реестр кодирований передачи
  7.4. Согласование кодирований передачи
8. Обработка неполных сообщений
9. Управление соединением
  9.1. Установление
  9.2. Сопоставление ответа с запросом
  9.3. Постоянные соединения
    9.3.1. Повторные запросы
    9.3.2. Конвейеризация
  9.4. Одновременные соединения
  9.5. Сбои и время ожидания
  9.6. Закрытие соединения
  9.7. Установление соединения TLS
  9.8. Закрытие соединения TLS
10. Включение сообщений в качестве данных
  10.1. Тип данных message/http
  10.2. Тип данных application/http
11. Вопросы безопасности
  11.1. Разделение ответов
  11.2. Контрабанда запросов
  11.3. Целостность сообщений
  11.4. Конфиденциальность сообщений
12. Вопросы IANA
  12.1. Регистрация имён полей
  12.2. Регистрация типов данных
  12.3. Регистрация кодирований передачи
  12.4. Регистрация идентификатора протокола ALPN
13. Ссылки
  13.1. Нормативные ссылки
  13.2. Информационные ссылки
Приложение A. Сводная грамматика ABNF
Приложение B. Различия между HTTP и MIME
  B.1. MIME-Version
  B.2. Преобразование в каноническую форму
  B.3. Преобразование форматов даты
  B.4. Преобразование Content-Encoding
  B.5. Преобразование Content-Transfer-Encoding
  B.6. MHTML и ограничения длины строк
Приложение C. Изменения по сравнению с предыдущими RFC
  C.1. Изменения по сравнению с HTTP/0.9
  C.2. Изменения по сравнению с HTTP/1.0
    C.2.1. Веб-серверы с несколькими адресами
    C.2.2. Соединения Keep-Alive
    C.2.3. Введение Transfer-Encoding
  C.3. Изменения по сравнению с RFC 7230
Благодарности
Указатель
Адреса авторов

1. Введение

Протокол передачи гипертекста (HTTP) — это не сохраняющий состояние протокол прикладного уровня, основанный на запросах и ответах. Он использует расширяемую семантику и самоописывающиеся сообщения для гибкого взаимодействия с сетевыми гипертекстовыми информационными системами. HTTP/1.1 определён следующими документами:

Настоящий документ определяет, как семантика HTTP передаётся с использованием синтаксиса сообщений, механизмов определения границ сообщений и управления соединениями HTTP/1.1. Его цель — определить полный набор требований к средствам разбора сообщений HTTP/1.1 и посредникам, пересылающим сообщения.

Настоящий документ заменяет части RFC 7230, относящиеся к обмену сообщениями и управлению соединениями HTTP/1.1; изменения кратко изложены в приложении C.3. Остальные части RFC 7230 заменены документом «HTTP Semantics» [HTTP].

1.1. Обозначение требований

Ключевые слова «MUST», «MUST NOT», «REQUIRED», «SHALL», «SHALL NOT», «SHOULD», «SHOULD NOT», «RECOMMENDED», «NOT RECOMMENDED», «MAY» и «OPTIONAL» в этом документе следует понимать согласно BCP 14 [RFC2119] [RFC8174] тогда и только тогда, когда они полностью написаны прописными буквами, как здесь.

Критерии соответствия и вопросы, касающиеся обработки ошибок, определены в разделе 2 [HTTP].

1.2. Обозначения синтаксиса

В этой спецификации используется расширенная форма Бэкуса — Наура (ABNF) из [RFC5234], дополненная обозначениями чувствительности строк к регистру, определёнными в [RFC7405].

Также используется расширение для списков, определённое в разделе 5.6.1 [HTTP], которое позволяет компактно определять списки, разделённые запятыми, с помощью оператора «#» (аналогично тому, как оператор «*» обозначает повторение). В приложении A приведена собранная грамматика, в которой все операторы списков раскрыты в стандартную запись ABNF.

По соглашению имена правил ABNF с префиксом «obs-» обозначают устаревшие правила грамматики, присутствующие по историческим причинам.

Следующие основные правила включены посредством ссылки в том виде, в котором они определены в приложении B.1 [RFC5234]: ALPHA (буквы), CR (возврат каретки), CRLF (CR LF), CTL (управляющие символы), DIGIT (десятичные цифры 0–9), DQUOTE (двойная кавычка), HEXDIG (шестнадцатеричные цифры 0–9/A–F/a–f), HTAB (горизонтальная табуляция), LF (перевод строки), OCTET (любая 8-битная последовательность данных), SP (пробел) и VCHAR (любой видимый символ [USASCII]).

Следующие правила определены в [HTTP]:

BWS           = <BWS, see [HTTP], Section 5.6.3>
OWS           = <OWS, see [HTTP], Section 5.6.3>
RWS           = <RWS, see [HTTP], Section 5.6.3>
absolute-path = <absolute-path, see [HTTP], Section 4.1>
field-name    = <field-name, see [HTTP], Section 5.1>
field-value   = <field-value, see [HTTP], Section 5.5>
obs-text      = <obs-text, see [HTTP], Section 5.6.4>
quoted-string = <quoted-string, see [HTTP], Section 5.6.4>
token         = <token, see [HTTP], Section 5.6.2>
transfer-coding =
                <transfer-coding, see [HTTP], Section 10.1.4>

Следующие правила определены в [URI]:

absolute-URI  = <absolute-URI, see [URI], Section 4.3>
authority     = <authority, see [URI], Section 3.2>
uri-host      = <host, see [URI], Section 3.2.2>
port          = <port, see [URI], Section 3.2.3>
query         = <query, see [URI], Section 3.4>

2. Сообщение

Клиенты и серверы HTTP/1.1 взаимодействуют, отправляя сообщения. Общая терминология и основные понятия HTTP приведены в разделе 3 [HTTP].

2.1. Формат сообщения

Сообщение HTTP/1.1 состоит из начальной строки (start-line), за которой следуют CRLF и последовательность октетов в формате, подобном формату интернет-сообщений [RFC5322]: ноль или более строк полей заголовка (в совокупности называемых «заголовками» или «секцией заголовка»), пустая строка, обозначающая конец секции заголовка, и необязательное тело сообщения.

HTTP-message   = start-line CRLF
                 *( field-line CRLF )
                 CRLF
                 [ message-body ]

Сообщение может быть запросом от клиента к серверу или ответом от сервера клиенту. Синтаксически эти два типа сообщений отличаются только начальной строкой — строкой запроса (request-line) для запросов или строкой состояния (status-line) для ответов — и алгоритмом определения длины тела сообщения (раздел 6).

start-line     = request-line / status-line

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

HTTP использует некоторые элементы протокола, аналогичные многоцелевым расширениям интернет-почты (MIME) [RFC2045]. Различия между сообщениями HTTP и MIME приведены в приложении B.

2.2. Разбор сообщения

Обычная процедура разбора сообщения HTTP состоит в том, чтобы прочитать начальную строку в структуру, затем до пустой строки прочитать каждую строку поля заголовка в хеш-таблицу по имени поля и после этого использовать разобранные данные для определения того, ожидается ли тело сообщения. Если наличие тела сообщения было указано, оно читается как поток, пока не будет прочитано количество октетов, равное длине тела сообщения, либо пока соединение не будет закрыто.

Получатель ОБЯЗАН (MUST) разбирать сообщение HTTP как последовательность октетов в кодировке, являющейся надмножеством US-ASCII [USASCII]. Разбор сообщения HTTP как потока символов Unicode без учёта конкретной кодировки создаёт уязвимости безопасности из-за различий в том, как библиотеки обработки строк обрабатывают недопустимые многобайтовые последовательности символов, содержащие октет LF (%x0A). Средства разбора строк можно безопасно использовать только внутри элементов протокола после извлечения элемента из сообщения, например внутри значения строки поля заголовка после того, как при разборе сообщения были определены границы отдельных строк полей.

Хотя завершителем начальной строки и полей является последовательность CRLF, получатель МОЖЕТ (MAY) распознавать одиночный LF как завершитель строки и игнорировать любой предшествующий CR.

Отправителю ЗАПРЕЩЕНО (MUST NOT) создавать одиночный CR (символ CR, за которым непосредственно не следует LF) внутри любых элементов протокола, кроме содержимого. Получатель такого одиночного CR ОБЯЗАН (MUST) либо считать соответствующий элемент недопустимым, либо заменить каждый одиночный CR на SP перед обработкой элемента или пересылкой сообщения.

Старые реализации пользовательских агентов HTTP/1.0 могли отправлять дополнительный CRLF после запроса POST в качестве обходного решения для некоторых ранних серверных приложений, которым не удавалось прочитать содержимое тела сообщения, не завершённое концом строки. Пользовательскому агенту HTTP/1.1 ЗАПРЕЩЕНО (MUST NOT) добавлять дополнительный CRLF перед запросом или после него. Если требуется завершить тело сообщения запроса концом строки, пользовательский агент ОБЯЗАН (MUST) включить октеты завершающего CRLF в длину тела сообщения.

В целях устойчивости серверу, ожидающему получения и разбора строки запроса, СЛЕДУЕТ (SHOULD) игнорировать по крайней мере одну пустую строку (CRLF), полученную перед строкой запроса.

Отправителю ЗАПРЕЩЕНО (MUST NOT) отправлять пробельные символы между начальной строкой и первым полем заголовка.

Получатель, получивший пробельные символы между начальной строкой и первым полем заголовка, ОБЯЗАН (MUST) либо отклонить сообщение как недопустимое, либо считать каждую строку, начинающуюся с пробельного символа, без её дальнейшей обработки (то есть игнорировать строку целиком вместе со всеми последующими строками, начинающимися с пробельного символа, до получения правильно сформированного поля заголовка или завершения секции заголовка). Отклонение или удаление недопустимых строк, начинающихся с пробельного символа, необходимо, чтобы их неверно не истолковали последующие получатели, которые могут быть уязвимы к атакам с контрабандой запросов (раздел 11.2) или разделением ответов (раздел 11.1).

Если сервер, принимающий только сообщения запросов HTTP либо обрабатывающий то, что по начальной строке выглядит как сообщение запроса HTTP, получает последовательность октетов, не соответствующую грамматике HTTP-message с учётом перечисленных выше исключений для устойчивости, серверу СЛЕДУЕТ (SHOULD) ответить сообщением 400 (Bad Request) и закрыть соединение.

2.3. Версия HTTP

Для обозначения версий протокола HTTP использует схему нумерации «<major>.<minor>». Эта спецификация определяет версию «1.1». Семантика номеров версий HTTP определена в разделе 2.5 [HTTP].

Версия сообщения HTTP/1.x указывается полем HTTP-version в начальной строке. HTTP-version чувствительно к регистру.

HTTP-version  = HTTP-name "/" DIGIT "." DIGIT
HTTP-name     = %s"HTTP"

При отправке сообщения HTTP/1.1 получателю HTTP/1.0 [HTTP/1.0] или получателю, версия которого неизвестна, сообщение HTTP/1.1 строится так, чтобы его можно было интерпретировать как допустимое сообщение HTTP/1.0, если игнорировать все более новые возможности. В отношении некоторых новых возможностей эта спецификация устанавливает требования к версии получателя, чтобы соответствующий ей отправитель использовал только совместимые возможности, пока посредством конфигурации или получения сообщения не определит, что получатель поддерживает HTTP/1.1.

Посредники, обрабатывающие сообщения HTTP (то есть все посредники, кроме действующих как туннели), ОБЯЗАНЫ (MUST) отправлять собственное значение HTTP-version в пересылаемых сообщениях, если только оно не понижено намеренно для обхода проблемы на вышестоящем узле. Иными словами, посреднику не разрешается вслепую пересылать начальную строку, не убедившись, что версия протокола в этом сообщении соответствует версии, которой посредник соответствует как при получении, так и при отправке сообщений. Пересылка сообщения HTTP без перезаписи HTTP-version может привести к ошибкам связи, когда последующие получатели используют версию отправителя сообщения, чтобы определить, какие возможности безопасно использовать при дальнейшем взаимодействии с этим отправителем.

Сервер МОЖЕТ (MAY) отправить ответ HTTP/1.0 на запрос HTTP/1.1, если известно или предполагается, что клиент неправильно реализует спецификацию HTTP и не способен корректно обрабатывать ответы более поздних версий — например, когда клиент неправильно разбирает номер версии либо известно, что посредник вслепую пересылает HTTP-version, даже не соответствуя указанной младшей версии протокола. Такое понижение версии протокола НЕ СЛЕДУЕТ (SHOULD NOT) выполнять, если оно не вызвано конкретными признаками клиента, например когда одно или несколько полей заголовка запроса (таких как User-Agent) однозначно совпадают со значениями, отправляемыми клиентом, о котором известно, что он работает неправильно.

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

Строка запроса (request-line) начинается с токена метода, за которым следуют один пробел (SP), цель запроса (request-target) и ещё один пробел (SP), и заканчивается версией протокола.

request-line   = method SP request-target SP HTTP-version

Хотя правило грамматики request-line требует отделять каждый составной элемент одним октетом SP, получатели МОГУТ (MAY) вместо этого выполнять разбор по границам слов, разделённых пробельными символами, и, за исключением завершающего CRLF, рассматривать любую форму пробельных символов как разделитель SP, игнорируя пробельные символы в начале или конце. Такие пробельные символы включают один или более следующих октетов: SP, HTAB, VT (%x0B), FF (%x0C) или одиночный CR. Однако снисходительный разбор может привести к уязвимостям безопасности, связанным с контрабандой запросов, если сообщение получает несколько получателей и каждый по-своему понимает устойчивость (см. раздел 11.2).

HTTP не устанавливает заранее определённого ограничения длины строки запроса, как описано в разделе 2.3 [HTTP]. Серверу, получившему метод, более длинный, чем любой из реализованных им методов, СЛЕДУЕТ (SHOULD) ответить кодом состояния 501 (Not Implemented). Сервер, получивший request-target длиннее любого URI, который он готов разбирать, ОБЯЗАН (MUST) ответить кодом состояния 414 (URI Too Long) (см. раздел 15.5.15 [HTTP]).

На практике встречаются различные специальные ограничения длины строки запроса. Всем отправителям и получателям HTTP РЕКОМЕНДУЕТСЯ (RECOMMENDED) поддерживать строки запроса длиной не менее 8000 октетов.

3.1. Метод

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

method         = token

Методы запроса, определённые этой спецификацией, приведены в разделе 9 [HTTP] вместе со сведениями о реестре методов HTTP и вопросами определения новых методов.

3.2. Цель запроса

Цель запроса (request-target) определяет целевой ресурс, к которому применяется запрос. Клиент получает request-target из нужного ему целевого URI. Существуют четыре различных формата request-target, выбор которых зависит как от запрашиваемого метода, так и от того, направлен ли запрос прокси-серверу.

request-target = origin-form
               / absolute-form
               / authority-form
               / asterisk-form

Пробельные символы в request-target не допускаются. К сожалению, некоторые пользовательские агенты неправильно кодируют или не исключают пробельные символы, обнаруженные в гипертекстовых ссылках, вследствие чего эти недопустимые символы отправляются в качестве request-target в неправильно сформированной строке запроса.

Получателям недопустимой строки запроса СЛЕДУЕТ (SHOULD) ответить либо ошибкой 400 (Bad Request), либо перенаправлением 301 (Moved Permanently) с правильно закодированным request-target. Получателю НЕ СЛЕДУЕТ (SHOULD NOT) пытаться автоматически исправить запрос и затем обработать его без перенаправления, поскольку недопустимая строка запроса могла быть намеренно сформирована для обхода фильтров безопасности вдоль цепочки запросов.

Клиент ОБЯЗАН (MUST) отправлять поле заголовка Host (раздел 7.2 [HTTP]) во всех сообщениях запросов HTTP/1.1. Если целевой URI включает компонент authority, клиент ОБЯЗАН (MUST) отправить значение поля Host, идентичное этому компоненту authority, за исключением любого подкомпонента userinfo и его разделителя «@» (раздел 4.2 [HTTP]). Если компонент authority в целевом URI отсутствует или не определён, клиент ОБЯЗАН (MUST) отправить поле заголовка Host с пустым значением.

Сервер ОБЯЗАН (MUST) ответить кодом состояния 400 (Bad Request) на любое сообщение запроса HTTP/1.1 без поля заголовка Host, а также на любое сообщение запроса, содержащее более одной строки поля заголовка Host либо поле заголовка Host с недопустимым значением.

3.2.1. origin-form

Наиболее распространённая форма request-target — «origin-form».

origin-form    = absolute-path [ "?" query ]

При отправке запроса непосредственно исходному серверу, кроме запроса CONNECT или OPTIONS для всего сервера (как подробно описано ниже), клиент ОБЯЗАН (MUST) отправлять в качестве request-target только компоненты абсолютного пути и строки запроса целевого URI. Если компонент пути целевого URI пуст, клиент ОБЯЗАН (MUST) отправить «/» в качестве пути в форме origin-form для request-target. Также отправляется поле заголовка Host, как определено в разделе 7.2 [HTTP].

Например, клиент, желающий получить представление ресурса, определяемого как

http://www.example.org/where?q=now

непосредственно с исходного сервера, откроет (или повторно использует) TCP-соединение с портом 80 узла «www.example.org» и отправит строки:

GET /where?q=now HTTP/1.1
Host: www.example.org

а затем остальную часть сообщения запроса.

3.2.2. absolute-form

При отправке запроса прокси-серверу, кроме запроса CONNECT или OPTIONS для всего сервера (как подробно описано ниже), клиент ОБЯЗАН (MUST) отправлять целевой URI в форме «absolute-form» в качестве request-target.

absolute-form  = absolute-URI

Прокси-серверу предлагается либо по возможности обслужить этот запрос из действительного кэша, либо выполнить тот же запрос от имени клиента к следующему прокси-серверу по направлению к источнику или непосредственно к исходному серверу, указанному в request-target. Требования к такой «пересылке» сообщений определены в разделе 7.6 [HTTP].

Пример строки запроса с absolute-form:

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

Клиент ОБЯЗАН (MUST) отправлять поле заголовка Host в запросе HTTP/1.1 даже тогда, когда request-target имеет форму absolute-form, поскольку это позволяет передавать сведения Host через очень старые прокси-серверы HTTP/1.0, которые могли не реализовывать Host.

Когда прокси-сервер получает запрос с request-target в форме absolute-form, он ОБЯЗАН (MUST) игнорировать полученное поле заголовка Host (если оно есть) и вместо этого заменить его сведениями об узле из request-target. Прокси-сервер, пересылающий такой запрос, ОБЯЗАН (MUST) сформировать новое значение поля Host на основе полученного request-target, а не пересылать полученное значение поля Host.

Когда исходный сервер получает запрос с request-target в форме absolute-form, он ОБЯЗАН (MUST) игнорировать полученное поле заголовка Host (если оно есть) и вместо этого использовать сведения об узле из request-target. Обратите внимание: если request-target не содержит компонента authority, в этом случае будет отправлено пустое поле заголовка Host.

Сервер ОБЯЗАН (MUST) принимать в запросах форму absolute-form, хотя большинство клиентов HTTP/1.1 отправляют absolute-form только прокси-серверу.

3.2.3. authority-form

Форма «authority-form» для request-target используется только в запросах CONNECT (раздел 9.3.6 [HTTP]). Она состоит только из uri-host и номера порта назначения туннеля, разделённых двоеточием («:»).

authority-form = uri-host ":" port

При отправке запроса CONNECT для установления туннеля через один или несколько прокси-серверов клиент ОБЯЗАН (MUST) отправлять в качестве request-target только узел и порт назначения туннеля. Клиент получает узел и порт из компонента authority целевого URI, за исключением того, что он отправляет порт схемы по умолчанию, если целевой URI не содержит порта. Например, запрос CONNECT к «http://www.example.com» выглядит следующим образом:

CONNECT www.example.com:80 HTTP/1.1
Host: www.example.com

3.2.4. asterisk-form

Форма «asterisk-form» для request-target используется только для запроса OPTIONS ко всему серверу (раздел 9.3.7 [HTTP]).

asterisk-form  = "*"

Когда клиент хочет запросить OPTIONS для сервера в целом, а не для конкретного именованного ресурса этого сервера, клиент ОБЯЗАН (MUST) отправить в качестве request-target только «*» (%x2A). Например:

OPTIONS * HTTP/1.1

Если прокси-сервер получает запрос OPTIONS с request-target в форме absolute-form, в котором URI имеет пустой путь и не имеет компонента query, последний прокси-сервер в цепочке запросов ОБЯЗАН (MUST) отправить request-target «*» при пересылке запроса указанному исходному серверу.

Например, запрос

OPTIONS http://www.example.org:8001 HTTP/1.1

последний прокси-сервер перешлёт в виде

OPTIONS * HTTP/1.1
Host: www.example.org:8001

после подключения к порту 8001 узла «www.example.org».

3.3. Восстановление целевого URI

Целевым URI является request-target, когда request-target имеет форму absolute-form. В этом случае сервер разбирает URI на общие компоненты для дальнейшей обработки.

В противном случае сервер восстанавливает целевой URI из контекста соединения и различных частей сообщения запроса, чтобы определить целевой ресурс (раздел 7.1 [HTTP]):

Пример 1. Следующее сообщение, полученное по защищённому соединению,

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

имеет целевой URI

https://www.example.org/pub/WWW/TheProject.html

Пример 2. Следующее сообщение, полученное по незащищённому соединению,

OPTIONS * HTTP/1.1
Host: www.example.org:8080

имеет целевой URI

http://www.example.org:8080

Если компонент authority целевого URI пуст, а его схема URI требует непустого authority (как в случае «http» и «https»), сервер может отклонить запрос или определить, применимо ли настроенное значение по умолчанию, согласованное с контекстом входящего соединения. Контекст может включать сведения о соединении, такие как адрес и порт, применённые средства защиты и локально определённую информацию, специфичную для конфигурации этого сервера. Перед дальнейшей обработкой запроса пустой authority заменяется настроенным значением по умолчанию.

Задание имени authority по умолчанию в контексте защищённого соединения изначально небезопасно, если существует хотя бы вероятность, что authority, предназначенный пользовательским агентом, отличается от значения по умолчанию. Сервер, способный однозначно определить authority из контекста запроса, МОЖЕТ (MAY) использовать это значение по умолчанию без такого риска. В качестве альтернативы может быть лучше перенаправить запрос к безопасному ресурсу, объясняющему, как получить новый клиент.

Обратите внимание, что восстановление целевого URI клиента — лишь половина процесса определения целевого ресурса. Другая половина состоит в определении того, указывает ли этот целевой URI на ресурс, для которого сервер готов и способен отправить ответ, как определено в разделе 7.4 [HTTP].

4. Строка состояния

Первая строка сообщения ответа — строка состояния (status-line), состоящая из версии протокола, пробела (SP), кода состояния и ещё одного пробела и заканчивающаяся НЕОБЯЗАТЕЛЬНОЙ (OPTIONAL) текстовой фразой, описывающей код состояния.

status-line = HTTP-version SP status-code SP [ reason-phrase ]

Хотя правило грамматики status-line требует отделять каждый составной элемент одним октетом SP, получатели МОГУТ (MAY) вместо этого выполнять разбор по границам слов, разделённых пробельными символами, и, за исключением завершителя строки, рассматривать любую форму пробельных символов как разделитель SP, игнорируя пробельные символы в начале или конце. Такие пробельные символы включают один или более следующих октетов: SP, HTAB, VT (%x0B), FF (%x0C) или одиночный CR. Однако снисходительный разбор может привести к уязвимостям безопасности, связанным с разделением ответов, если сообщение получает несколько получателей и каждый по-своему понимает устойчивость (см. раздел 11.1).

Элемент status-code — это трёхзначный целочисленный код, описывающий результат попытки сервера понять и выполнить соответствующий запрос клиента. Получатель разбирает и интерпретирует остальную часть сообщения ответа с учётом семантики, определённой для этого кода состояния, если получатель распознаёт код, или в соответствии с классом кода состояния, если конкретный код не распознан.

status-code    = 3DIGIT

Основные коды состояния HTTP определены в разделе 15 [HTTP] вместе с классами кодов состояния, вопросами определения новых кодов состояния и реестром IANA для сбора таких определений.

Элемент reason-phrase существует исключительно для предоставления текстового описания, связанного с числовым кодом состояния, главным образом в знак уважения к более ранним прикладным протоколам Интернета, которые чаще использовались с интерактивными текстовыми клиентами.

reason-phrase  = 1*( HTAB / SP / VCHAR / obs-text )

Клиенту СЛЕДУЕТ (SHOULD) игнорировать содержимое reason-phrase, поскольку это ненадёжный канал передачи информации: фраза может быть переведена для определённой локали, перезаписана посредниками или отброшена при пересылке сообщения через другие версии HTTP. Сервер ОБЯЗАН (MUST) отправлять пробел, отделяющий status-code от reason-phrase, даже когда reason-phrase отсутствует (то есть status-line будет заканчиваться пробелом).

5. Синтаксис полей

Каждая строка поля состоит из нечувствительного к регистру имени поля, за которым следуют двоеточие («:»), необязательные начальные пробельные символы, значение строки поля и необязательные конечные пробельные символы.

field-line   = field-name ":" OWS field-value OWS

Правила разбора внутри значений полей определены в разделе 5.5 [HTTP]. В этом разделе рассматривается общий синтаксис включения полей заголовка в сообщения HTTP/1.1 и их извлечения из них.

5.1. Разбор строки поля

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

Между именем поля и двоеточием пробельные символы не допускаются. В прошлом различия в обработке таких пробельных символов приводили к уязвимостям безопасности при маршрутизации запросов и обработке ответов. Сервер ОБЯЗАН (MUST) отклонить с кодом состояния ответа 400 (Bad Request) любое полученное сообщение запроса, содержащее пробельные символы между именем поля заголовка и двоеточием. Прокси-сервер ОБЯЗАН (MUST) удалить любые такие пробельные символы из сообщения ответа перед его пересылкой далее по цепочке.

Перед значением строки поля и/или после него могут находиться необязательные пробельные символы (OWS); для единообразной удобочитаемости человеком предпочтителен один SP перед значением строки поля. Значение строки поля не включает эти начальные или конечные пробельные символы: средства разбора исключают OWS перед первым непробельным октетом значения строки поля или после последнего непробельного октета при извлечении значения из строки поля.

5.2. Устаревший перенос строк

Исторически значения полей HTTP/1.x могли распространяться на несколько строк, если перед каждой дополнительной строкой ставился хотя бы один пробел или символ горизонтальной табуляции (obs-fold). Эта спецификация объявляет такой перенос строк устаревшим, за исключением типа данных «message/http» (раздел 10.1).

obs-fold     = OWS CRLF RWS
             ; obsolete line folding

Отправителю ЗАПРЕЩЕНО (MUST NOT) создавать сообщение с переносом строк (то есть содержащее любое значение строки поля, соответствующее правилу obs-fold), если сообщение не предназначено для упаковки в тип данных «message/http».

Сервер, получивший obs-fold в сообщении запроса вне контейнера «message/http», ОБЯЗАН (MUST) либо отклонить сообщение, отправив 400 (Bad Request), предпочтительно с представлением, объясняющим, что устаревший перенос строк недопустим, либо заменить каждый полученный obs-fold одним или несколькими октетами SP до интерпретации значения поля или пересылки сообщения далее по цепочке.

Прокси-сервер или шлюз, получивший obs-fold в сообщении ответа вне контейнера «message/http», ОБЯЗАН (MUST) либо отбросить сообщение и заменить его ответом 502 (Bad Gateway), предпочтительно с представлением, объясняющим, что получен недопустимый перенос строк, либо заменить каждый полученный obs-fold одним или несколькими октетами SP до интерпретации значения поля или пересылки сообщения далее по цепочке.

Пользовательский агент, получивший obs-fold в сообщении ответа вне контейнера «message/http», ОБЯЗАН (MUST) заменить каждый полученный obs-fold одним или несколькими октетами SP до интерпретации значения поля.

6. Тело сообщения

Тело сообщения HTTP/1.1 (если оно есть) используется для передачи содержимого (раздел 6.4 [HTTP]) запроса или ответа. Тело сообщения идентично содержимому, если не было применено кодирование передачи, как описано в разделе 6.1.

message-body = *OCTET

Правила определения наличия тела в сообщении HTTP/1.1 различаются для запросов и ответов.

О наличии тела в запросе сигнализирует поле заголовка Content-Length или Transfer-Encoding. Определение границ сообщения запроса не зависит от семантики метода.

Наличие тела в ответе, как подробно описано в разделе 6.3, зависит как от метода запроса, на который он отвечает, так и от кода состояния ответа. Это соответствует условиям, при которых семантика HTTP допускает содержимое ответа (раздел 6.4.1 [HTTP]).

6.1. Transfer-Encoding

Поле заголовка Transfer-Encoding перечисляет имена кодирований передачи, соответствующие последовательности кодирований передачи, которые были (или будут) применены к содержимому для формирования тела сообщения. Кодирования передачи определены в разделе 7.

Transfer-Encoding = #transfer-coding
                     ; defined in [HTTP], Section 10.1.4

Transfer-Encoding аналогично полю MIME Content-Transfer-Encoding, которое было разработано для обеспечения безопасной передачи двоичных данных через 7-битную транспортную службу ([RFC2045], раздел 6). Однако для протокола передачи, сохраняющего все 8 бит, безопасная передача имеет другую направленность. В HTTP поле Transfer-Encoding предназначено прежде всего для точного определения границ динамически формируемого содержимого. Оно также служит для разграничения кодирований, применяемых только при передаче, и кодирований, характеризующих выбранное представление.

Получатель ОБЯЗАН (MUST) уметь разбирать кодирование передачи chunked (раздел 7.1), поскольку оно играет важнейшую роль в определении границ сообщений, когда размер содержимого заранее неизвестен. Отправителю ЗАПРЕЩЕНО (MUST NOT) применять кодирование передачи chunked к телу сообщения более одного раза (то есть разбивать на части уже разбитое сообщение не допускается). Если к содержимому запроса применяется любое кодирование передачи, кроме chunked, отправитель ОБЯЗАН (MUST) применить chunked как последнее кодирование передачи, чтобы обеспечить правильное определение границ сообщения. Если к содержимому ответа применяется любое кодирование передачи, кроме chunked, отправитель ОБЯЗАН (MUST) либо применить chunked как последнее кодирование передачи, либо завершить сообщение закрытием соединения.

Например,

Transfer-Encoding: gzip, chunked

указывает, что при формировании тела сообщения содержимое было сжато с использованием кодирования gzip, а затем разбито на части с использованием кодирования chunked.

В отличие от Content-Encoding (раздел 8.4.1 [HTTP]), Transfer-Encoding является свойством сообщения, а не представления. Любой получатель в цепочке запроса/ответа МОЖЕТ (MAY) декодировать полученные кодирования передачи или применять дополнительные кодирования передачи к телу сообщения при условии внесения соответствующих изменений в значение поля Transfer-Encoding. Дополнительную информацию о параметрах кодирования могут предоставлять другие поля заголовка, не определённые этой спецификацией.

Transfer-Encoding МОЖЕТ (MAY) быть отправлено в ответе на запрос HEAD или в ответе 304 (Not Modified) (раздел 15.4.5 [HTTP]) на запрос GET, ни один из которых не содержит тела сообщения, чтобы указать, что исходный сервер применил бы кодирование передачи к телу сообщения, если бы запрос был безусловным GET. Однако такое указание не требуется, поскольку любой получатель в цепочке ответа (включая исходный сервер) может удалить кодирования передачи, когда они не нужны.

Серверу ЗАПРЕЩЕНО (MUST NOT) отправлять поле заголовка Transfer-Encoding в любом ответе с кодом состояния 1xx (Informational) или 204 (No Content). Серверу ЗАПРЕЩЕНО (MUST NOT) отправлять поле заголовка Transfer-Encoding в любом ответе 2xx (Successful) на запрос CONNECT (раздел 9.3.6 [HTTP]).

Серверу, получившему сообщение запроса с непонятным ему кодированием передачи, СЛЕДУЕТ (SHOULD) ответить 501 (Not Implemented).

Transfer-Encoding было добавлено в HTTP/1.1. Обычно предполагается, что реализации, объявляющие поддержку только HTTP/1.0, не знают, как обрабатывать содержимое с кодированием передачи, а сообщение HTTP/1.0, полученное с Transfer-Encoding, вероятно, было переслано без надлежащей обработки кодирования передачи chunked при передаче.

Клиенту ЗАПРЕЩЕНО (MUST NOT) отправлять запрос, содержащий Transfer-Encoding, если ему не известно, что сервер обрабатывает запросы HTTP/1.1 (или более поздних младших версий); такое знание может быть получено из конкретной пользовательской конфигурации или путём запоминания версии ранее полученного ответа. Серверу ЗАПРЕЩЕНО (MUST NOT) отправлять ответ, содержащий Transfer-Encoding, если соответствующий запрос не указывает HTTP/1.1 (или более позднюю младшую версию).

Ранние реализации Transfer-Encoding иногда отправляли одновременно кодирование передачи chunked для определения границ сообщения и поле заголовка Content-Length с приблизительной длиной для использования индикаторами выполнения. Именно поэтому Transfer-Encoding определено как имеющее приоритет над Content-Length, а не как несовместимое с ним. К сожалению, пересылка такого сообщения может привести к уязвимостям, связанным с атаками с контрабандой запросов (раздел 11.2) или разделением ответов (раздел 11.1), если какой-либо последующий получатель разбирает сообщение не в соответствии с этой спецификацией, особенно когда он реализует только HTTP/1.0.

Сервер МОЖЕТ (MAY) отклонить запрос, содержащий и Content-Length, и Transfer-Encoding, либо обработать такой запрос только в соответствии с Transfer-Encoding. В любом случае сервер ОБЯЗАН (MUST) закрыть соединение после ответа на такой запрос, чтобы избежать возможных атак.

Сервер или клиент, получивший сообщение HTTP/1.0 с полем заголовка Transfer-Encoding, ОБЯЗАН (MUST) считать границы сообщения заданными ошибочно, даже при наличии Content-Length, и закрыть соединение после обработки сообщения. Отправитель сообщения мог сохранить часть сообщения в буфере, и при дальнейшем использовании соединения она могла бы быть неправильно истолкована.

6.2. Content-Length

Если сообщение не содержит поля заголовка Transfer-Encoding, поле заголовка Content-Length (раздел 8.6 [HTTP]) может указывать ожидаемый размер возможного содержимого как десятичное число октетов. Для сообщений, содержащих содержимое, значение поля Content-Length предоставляет сведения о границах, необходимые для определения конца данных (и сообщения). Для сообщений, не содержащих содержимого, Content-Length указывает размер выбранного представления (раздел 8.6 [HTTP]).

Отправителю ЗАПРЕЩЕНО (MUST NOT) отправлять поле заголовка Content-Length в любом сообщении, содержащем поле заголовка Transfer-Encoding.

Примечание. Использование Content-Length в HTTP для определения границ сообщений существенно отличается от использования того же поля в MIME, где это необязательное поле, применяемое только в типе данных «message/external-body».

6.3. Длина тела сообщения

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

  1. Любой ответ на запрос HEAD и любой ответ с кодом состояния 1xx (Informational), 204 (No Content) или 304 (Not Modified) всегда завершается первой пустой строкой после полей заголовка независимо от присутствующих в сообщении полей заголовка и, следовательно, не может содержать тело сообщения или секцию трейлера.
  2. Любой ответ 2xx (Successful) на запрос CONNECT означает, что соединение станет туннелем сразу после пустой строки, завершающей поля заголовка. Клиент ОБЯЗАН (MUST) игнорировать любые поля заголовка Content-Length или Transfer-Encoding, полученные в таком сообщении.
  3. Если сообщение получено и с полем заголовка Transfer-Encoding, и с полем заголовка Content-Length, Transfer-Encoding имеет приоритет над Content-Length. Такое сообщение может указывать на попытку контрабанды запросов (раздел 11.2) или разделения ответов (раздел 11.1), и его следует обрабатывать как ошибку. Посредник, решивший переслать сообщение, ОБЯЗАН (MUST) сначала удалить полученное поле Content-Length и обработать Transfer-Encoding (как описано ниже), прежде чем переслать сообщение далее по цепочке.
  4. Если присутствует поле заголовка Transfer-Encoding и последним кодированием является кодирование передачи chunked (раздел 7.1), длина тела сообщения определяется чтением и декодированием данных chunked до тех пор, пока кодирование передачи не укажет, что данные завершены.

    Если поле заголовка Transfer-Encoding присутствует в ответе и кодирование передачи chunked не является последним, длина тела сообщения определяется чтением соединения до его закрытия сервером.

    Если поле заголовка Transfer-Encoding присутствует в запросе и кодирование передачи chunked не является последним, длину тела сообщения нельзя надёжно определить; сервер ОБЯЗАН (MUST) ответить кодом состояния 400 (Bad Request), а затем закрыть соединение.

  5. Если сообщение получено без Transfer-Encoding и с недопустимым полем заголовка Content-Length, границы сообщения заданы недопустимым образом и получатель ОБЯЗАН (MUST) считать это неисправимой ошибкой, кроме случая, когда значение поля удаётся разобрать как список, разделённый запятыми (раздел 5.6.1 [HTTP]), все значения в списке допустимы и все они одинаковы (в этом случае сообщение обрабатывается с использованием этого единственного значения как значения поля Content-Length). Если неисправимая ошибка находится в сообщении запроса, сервер ОБЯЗАН (MUST) ответить кодом состояния 400 (Bad Request), а затем закрыть соединение. Если она находится в сообщении ответа, полученном прокси-сервером, прокси-сервер ОБЯЗАН (MUST) закрыть соединение с сервером, отбросить полученный ответ и отправить клиенту ответ 502 (Bad Gateway). Если она находится в сообщении ответа, полученном пользовательским агентом, пользовательский агент ОБЯЗАН (MUST) закрыть соединение с сервером и отбросить полученный ответ.
  6. Если присутствует допустимое поле заголовка Content-Length без Transfer-Encoding, его десятичное значение определяет ожидаемую длину тела сообщения в октетах. Если отправитель закрывает соединение или время ожидания получателя истекает до получения указанного числа октетов, получатель ОБЯЗАН (MUST) считать сообщение неполным и закрыть соединение.
  7. Если это сообщение запроса и ни одно из приведённых выше условий не выполнено, длина тела сообщения равна нулю (тело сообщения отсутствует).
  8. В противном случае это сообщение ответа без объявленной длины тела сообщения, поэтому длина тела определяется количеством октетов, полученных до закрытия соединения сервером.

Поскольку невозможно отличить успешно завершённое сообщение ответа, границы которого определяются закрытием соединения, от частично полученного сообщения, прерванного сетевым сбоем, серверу СЛЕДУЕТ (SHOULD) по возможности формировать сообщения с границами, заданными кодированием или длиной. Определение границ закрытием соединения существует главным образом для обратной совместимости с HTTP/1.0.

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

Сервер МОЖЕТ (MAY) отклонить запрос, содержащий тело сообщения, но не содержащий Content-Length, ответом 411 (Length Required).

Если не было применено кодирование передачи, отличное от chunked, клиенту, отправляющему запрос с телом сообщения, СЛЕДУЕТ (SHOULD) использовать допустимое поле заголовка Content-Length, если длина тела сообщения известна заранее, вместо кодирования передачи chunked, поскольку некоторые существующие службы отвечают на chunked кодом состояния 411 (Length Required), хотя и понимают кодирование передачи chunked. Обычно это происходит потому, что такие службы реализованы через шлюз, которому длина содержимого требуется заранее, до вызова, а сервер не может или не желает буферизовать весь запрос до его обработки.

Пользовательский агент, отправляющий запрос с телом сообщения, ОБЯЗАН (MUST) либо отправить допустимое поле заголовка Content-Length, либо использовать кодирование передачи chunked. Клиенту ЗАПРЕЩЕНО (MUST NOT) использовать кодирование передачи chunked, если ему не известно, что сервер обрабатывает запросы HTTP/1.1 (или более поздней версии); такое знание может быть получено из конкретной пользовательской конфигурации или путём запоминания версии ранее полученного ответа.

Если окончательный ответ на последний запрос в соединении получен полностью и остаются дополнительные данные для чтения, пользовательский агент МОЖЕТ (MAY) отбросить оставшиеся данные или попытаться определить, относятся ли они к телу предыдущего сообщения, что возможно, если значение Content-Length предыдущего сообщения неверно. Клиенту ЗАПРЕЩЕНО (MUST NOT) обрабатывать, кэшировать или пересылать такие дополнительные данные как отдельный ответ, поскольку такое поведение было бы уязвимо к отравлению кэша.

7. Кодирования передачи

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

Все имена transfer-coding нечувствительны к регистру и их следует регистрировать в реестре кодирований передачи HTTP, как определено в разделе 7.3. Они используются в полях заголовка Transfer-Encoding (раздел 6.1) и TE (раздел 10.1.4 [HTTP]); последнее также определяет грамматику «transfer-coding».

7.1. Кодирование передачи chunked

Кодирование передачи chunked оборачивает содержимое для передачи в виде последовательности частей (chunks), каждая из которых имеет собственный указатель размера, за которыми следует НЕОБЯЗАТЕЛЬНАЯ (OPTIONAL) секция трейлера, содержащая поля трейлера. Chunked позволяет передавать потоки содержимого неизвестного размера как последовательность буферов с границами, определяемыми длиной; это позволяет отправителю сохранять постоянное соединение, а получателю — знать, когда он получил всё сообщение.

chunked-body   = *chunk
                 last-chunk
                 trailer-section
                 CRLF

chunk          = chunk-size [ chunk-ext ] CRLF
                 chunk-data CRLF
chunk-size     = 1*HEXDIG
last-chunk     = 1*("0") [ chunk-ext ] CRLF

chunk-data     = 1*OCTET ; a sequence of chunk-size octets

Поле chunk-size — строка шестнадцатеричных цифр, указывающая размер chunk-data в октетах. Кодирование передачи chunked завершается после получения части с нулевым chunk-size, за которой может следовать секция трейлера, и заключительной пустой строки.

Получатель ОБЯЗАН (MUST) уметь разбирать и декодировать кодирование передачи chunked.

HTTP/1.1 не определяет никаких средств ограничения размера ответа chunked, которые позволяли бы посреднику быть уверенным в возможности буферизовать весь ответ. Кроме того, очень большие размеры частей могут вызвать переполнение или потерю точности, если их значения неточно представлены в получающей реализации. Поэтому получатели ОБЯЗАНЫ (MUST) учитывать возможность больших шестнадцатеричных чисел и предотвращать ошибки разбора из-за переполнения при преобразовании целых чисел или потери точности при их представлении.

Кодирование chunked не определяет никаких параметров. Их наличие СЛЕДУЕТ (SHOULD) считать ошибкой.

7.1.1. Расширения частей

Кодирование chunked позволяет каждой части включать ноль или более расширений части непосредственно после chunk-size для передачи метаданных отдельной части (например, подписи или хеша), управляющей информации внутри сообщения или рандомизации размера тела сообщения.

chunk-ext      = *( BWS ";" BWS chunk-ext-name
                    [ BWS "=" BWS chunk-ext-val ] )

chunk-ext-name = token
chunk-ext-val  = token / quoted-string

Кодирование chunked специфично для каждого соединения и, вероятно, будет удалено или перекодировано каждым получателем (включая посредников) до того, как какое-либо приложение более высокого уровня сможет изучить расширения. Поэтому использование расширений частей обычно ограничивается специализированными службами HTTP, такими как «длинный опрос» (где клиент и сервер могут иметь общие ожидания относительно использования расширений частей), или дополнением внутри сквозного защищённого соединения.

Получатель ОБЯЗАН (MUST) игнорировать нераспознанные расширения частей. Серверу следует ограничивать общую длину расширений частей, получаемых в запросе, величиной, разумной для предоставляемых служб, подобно тому как он применяет ограничения длины и времени ожидания к другим частям сообщения, и формировать соответствующий ответ 4xx (Client Error) при превышении этой величины.

7.1.2. Секция трейлера chunked

Секция трейлера позволяет отправителю включать дополнительные поля в конце сообщения chunked, чтобы предоставить метаданные, которые могут динамически формироваться при отправке содержимого, например данные проверки целостности сообщения, цифровую подпись или состояние последующей обработки. Правильное использование и ограничения полей трейлера определены в разделе 6.5 [HTTP].

trailer-section   = *( field-line CRLF )

Получатель, удаляющий кодирование chunked из сообщения, МОЖЕТ (MAY) выборочно сохранять или отбрасывать полученные поля трейлера. Получатель, сохраняющий полученное поле трейлера, ОБЯЗАН (MUST) либо хранить/пересылать поле трейлера отдельно от полученных полей заголовка, либо объединять полученное поле трейлера с секцией заголовка. Получателю ЗАПРЕЩЕНО (MUST NOT) объединять полученное поле трейлера с секцией заголовка, если только определение соответствующего поля заголовка явно не разрешает это и не указывает, как безопасно объединить значение поля трейлера.

7.1.3. Декодирование chunked

Процесс декодирования кодирования передачи chunked можно представить следующим псевдокодом:

length := 0
read chunk-size, chunk-ext (if any), and CRLF
while (chunk-size > 0) {
   read chunk-data and CRLF
   append chunk-data to content
   length := length + chunk-size
   read chunk-size, chunk-ext (if any), and CRLF
}
read trailer field
while (trailer field is not empty) {
   if (trailer fields are stored/forwarded separately) {
       append trailer field to existing trailer fields
   }
   else if (trailer field is understood and defined as mergeable) {
       merge trailer field with existing header fields
   }
   else {
       discard trailer field
   }
   read trailer field
}
Content-Length := length
Remove "chunked" from Transfer-Encoding

7.2. Кодирования передачи для сжатия

Следующие имена кодирований передачи для сжатия определены тем же алгоритмом, что и соответствующие им кодирования содержимого:

compress (и x-compress)
См. раздел 8.4.1.1 [HTTP].
deflate
См. раздел 8.4.1.2 [HTTP].
gzip (и x-gzip)
См. раздел 8.4.1.3 [HTTP].

Кодирования сжатия не определяют никаких параметров. Наличие параметров с любым из этих кодирований сжатия СЛЕДУЕТ (SHOULD) считать ошибкой.

7.3. Реестр кодирований передачи

«HTTP Transfer Coding Registry» определяет пространство имён кодирований передачи. Он ведётся по адресу https://www.iana.org/assignments/http-parameters.

Записи ОБЯЗАНЫ (MUST) включать следующие поля:

Именам кодирований передачи ЗАПРЕЩЕНО (MUST NOT) совпадать с именами кодирований содержимого (раздел 8.4.1 [HTTP]), если преобразование кодирования не является идентичным, как в случае кодирований сжатия, определённых в разделе 7.2.

Поле заголовка TE (раздел 10.1.4 [HTTP]) использует псевдопараметр «q» как значение ранга, когда приемлемо несколько кодирований передачи. Чтобы избежать неоднозначности, будущим регистрациям кодирований передачи НЕ СЛЕДУЕТ (SHOULD NOT) определять параметры с именем «q» без учёта регистра.

Значения, добавляемые в это пространство имён, требуют рассмотрения IETF (IETF Review; см. раздел 4.8 [RFC8126]) и ОБЯЗАНЫ (MUST) соответствовать назначению кодирования передачи, определённому в этой спецификации.

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

7.4. Согласование кодирований передачи

Поле TE (раздел 10.1.4 [HTTP]) используется в HTTP/1.1, чтобы указать, какие кодирования передачи, помимо chunked, клиент готов принять в ответе и готов ли клиент сохранять поля трейлера при кодировании передачи chunked.

Клиенту ЗАПРЕЩЕНО (MUST NOT) отправлять имя кодирования передачи chunked в TE; chunked всегда приемлемо для получателей HTTP/1.1.

Ниже приведены три примера использования TE.

TE: deflate
TE:
TE: trailers, deflate;q=0.5

Когда приемлемо несколько кодирований передачи, клиент МОЖЕТ (MAY) ранжировать их по предпочтению с помощью нечувствительного к регистру параметра «q» (аналогично значениям qvalue, используемым в полях согласования содержимого; см. раздел 12.4.2 [HTTP]). Значение ранга — действительное число в диапазоне от 0 до 1, где 0,001 означает наименее предпочтительное, а 1 — наиболее предпочтительное; значение 0 означает «неприемлемо».

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

Ключевое слово «trailers» указывает, что отправитель не будет отбрасывать поля трейлера, как описано в разделе 6.5 [HTTP].

Поскольку поле заголовка TE применяется только к непосредственному соединению, отправитель TE также ОБЯЗАН (MUST) отправлять параметр соединения «TE» в поле заголовка Connection (раздел 7.6.1 [HTTP]), чтобы предотвратить пересылку поля заголовка TE посредниками, не поддерживающими его семантику.

8. Обработка неполных сообщений

Сервер, получивший неполное сообщение запроса, обычно вследствие отмены запроса или срабатывания исключения по времени ожидания, МОЖЕТ (MAY) отправить ответ с ошибкой до закрытия соединения.

Клиент, получивший неполное сообщение ответа, что может произойти при преждевременном закрытии соединения или ошибке декодирования предполагаемого кодирования передачи chunked, ОБЯЗАН (MUST) отметить сообщение как неполное. Требования к кэшированию неполных ответов определены в разделе 3.3 [CACHING].

Если ответ заканчивается посреди секции заголовка (до получения пустой строки), а код состояния может зависеть от полей заголовка для передачи полного смысла ответа, клиент не может предполагать, что этот смысл был передан; клиенту может потребоваться повторить запрос, чтобы определить следующее действие.

Тело сообщения, использующее кодирование передачи chunked, является неполным, если не получена завершающая кодирование часть нулевого размера. Сообщение с допустимым Content-Length является неполным, если размер полученного тела сообщения (в октетах) меньше значения, указанного в Content-Length. Ответ, не содержащий ни кодирования передачи chunked, ни Content-Length, завершается закрытием соединения и, если секция заголовка получена целиком, считается полным, если только нижележащее соединение не сообщило об ошибке (например, «неполное закрытие» в TLS оставит ответ неполным, как описано в разделе 9.8).

9. Управление соединением

Обмен сообщениями HTTP не зависит от нижележащих протоколов соединения транспортного или сеансового уровня. HTTP предполагает только надёжный транспорт с доставкой запросов по порядку и соответствующей доставкой ответов по порядку. Отображение структур запросов и ответов HTTP на единицы данных нижележащего транспортного протокола выходит за рамки этой спецификации.

Как описано в разделе 7.3 [HTTP], конкретные протоколы соединения, используемые для взаимодействия HTTP, определяются конфигурацией клиента и целевым URI. Например, схема URI «http» (раздел 4.2.1 [HTTP]) указывает соединение TCP поверх IP по умолчанию с TCP-портом 80 по умолчанию, но клиент может быть настроен на использование прокси-сервера через другое соединение, порт или протокол.

Ожидается, что реализации HTTP управляют соединениями, включая ведение состояния текущих соединений, установление нового или повторное использование существующего соединения, обработку сообщений, полученных по соединению, обнаружение сбоев соединения и закрытие каждого соединения. Большинство клиентов поддерживают несколько параллельных соединений, в том числе более одного соединения на конечную точку сервера. Большинство серверов рассчитаны на поддержание тысяч одновременных соединений с управлением очередями запросов для обеспечения справедливого использования и обнаружения атак типа «отказ в обслуживании».

9.1. Установление

Описание установления соединений с помощью различных протоколов транспортного или сеансового уровня выходит за рамки этой спецификации. Каждому соединению HTTP соответствует одно нижележащее транспортное соединение.

9.2. Сопоставление ответа с запросом

HTTP/1.1 не включает идентификатор запроса для сопоставления конкретного сообщения запроса с соответствующими ему одним или несколькими сообщениями ответа. Поэтому он полагается на то, что порядок поступления ответов точно соответствует порядку отправки запросов по одному соединению. Более одного сообщения ответа на запрос бывает только тогда, когда одному окончательному ответу на тот же запрос предшествуют один или несколько информационных ответов (1xx; см. раздел 15.2 [HTTP]).

Клиент, имеющий более одного ожидающего ответа запроса на соединении, ОБЯЗАН (MUST) вести список таких запросов в порядке отправки и ОБЯЗАН (MUST) сопоставлять каждое полученное по этому соединению сообщение ответа с первым ожидающим запросом, на который ещё не получен окончательный ответ (не 1xx).

Если клиент получает данные по соединению, на котором нет ожидающих ответа запросов, клиенту ЗАПРЕЩЕНО (MUST NOT) считать эти данные допустимым ответом; клиенту СЛЕДУЕТ (SHOULD) закрыть соединение, поскольку определение границ сообщений теперь неоднозначно, если только данные не состоят исключительно из одного или нескольких CRLF (которые можно отбросить согласно разделу 2.2).

9.3. Постоянные соединения

По умолчанию HTTP/1.1 использует «постоянные соединения», позволяющие передавать несколько запросов и ответов по одному соединению. Реализациям HTTP СЛЕДУЕТ (SHOULD) поддерживать постоянные соединения.

Получатель определяет, является ли соединение постоянным, на основе версии протокола и поля заголовка Connection (раздел 7.6.1 [HTTP]) в последнем полученном сообщении, если оно есть:

Клиент, не поддерживающий постоянные соединения, ОБЯЗАН (MUST) отправлять параметр соединения «close» в каждом сообщении запроса.

Сервер, не поддерживающий постоянные соединения, ОБЯЗАН (MUST) отправлять параметр соединения «close» в каждом сообщении ответа, не имеющем кода состояния 1xx (Informational).

Клиент МОЖЕТ (MAY) отправлять дополнительные запросы по постоянному соединению, пока не отправит или не получит параметр соединения «close» либо не получит ответ HTTP/1.0 без параметра соединения «keep-alive».

Чтобы соединение оставалось постоянным, все сообщения в нём должны иметь самостоятельно определяемую длину (то есть не определяемую закрытием соединения), как описано в разделе 6. Сервер ОБЯЗАН (MUST) прочитать тело сообщения запроса целиком или закрыть соединение после отправки ответа; иначе оставшиеся данные постоянного соединения будут ошибочно интерпретированы как следующий запрос. Аналогично клиент ОБЯЗАН (MUST) прочитать тело сообщения ответа целиком, если намерен повторно использовать то же соединение для последующего запроса.

Прокси-серверу ЗАПРЕЩЕНО (MUST NOT) поддерживать постоянное соединение с клиентом HTTP/1.0 (сведения и обсуждение проблем с полем заголовка Keep-Alive, реализованным многими клиентами HTTP/1.0, см. в приложении C.2.2).

Дополнительные сведения об обратной совместимости с клиентами HTTP/1.0 см. в приложении C.2.2.

9.3.1. Повторные запросы

Соединения могут закрываться в любой момент, намеренно или нет. Реализациям следует предусматривать необходимость восстановления после асинхронных событий закрытия. Условия, при которых клиент может автоматически повторить последовательность ожидающих ответа запросов, определены в разделе 9.2.2 [HTTP].

9.3.2. Конвейеризация

Клиент, поддерживающий постоянные соединения, МОЖЕТ (MAY) «конвейеризировать» свои запросы (то есть отправлять несколько запросов, не дожидаясь каждого ответа). Сервер МОЖЕТ (MAY) обрабатывать последовательность конвейерных запросов параллельно, если все они используют безопасные методы (раздел 9.2.1 [HTTP]), но он ОБЯЗАН (MUST) отправлять соответствующие ответы в том же порядке, в котором получены запросы.

Клиенту, использующему конвейеризацию запросов, СЛЕДУЕТ (SHOULD) повторить запросы, оставшиеся без ответа, если соединение закрывается до получения всех соответствующих ответов. При повторении конвейерных запросов после сбоя соединения (соединения, не закрытого явно сервером в его последнем полном ответе) клиенту ЗАПРЕЩЕНО (MUST NOT) использовать конвейеризацию сразу после установления соединения, поскольку первый оставшийся запрос предыдущего конвейера мог вызвать ответ с ошибкой, который снова может быть потерян, если по преждевременно закрываемому соединению отправлено несколько запросов (см. проблему сброса TCP, описанную в разделе 9.6).

Идемпотентные методы (раздел 9.2.2 [HTTP]) важны для конвейеризации, поскольку их можно автоматически повторять после сбоя соединения. Пользовательскому агенту НЕ СЛЕДУЕТ (SHOULD NOT) конвейеризировать запросы после неидемпотентного метода до получения окончательного кода состояния ответа для этого метода, если только пользовательский агент не располагает средством обнаружения частичных сбоев в конвейерной последовательности и восстановления после них.

Посредник, получающий конвейерные запросы, МОЖЕТ (MAY) конвейеризировать их при пересылке по направлению к источнику, поскольку он может полагаться на пользовательские агенты на стороне клиента в определении того, какие запросы безопасно конвейеризировать. Если соединение по направлению к источнику прерывается до получения ответа, посредник, использующий конвейеризацию, МОЖЕТ (MAY) попытаться повторить последовательность запросов, на которые ещё не получен ответ, если все запросы используют идемпотентные методы; в противном случае посреднику СЛЕДУЕТ (SHOULD) переслать все полученные ответы, а затем закрыть соответствующие соединения на стороне клиента, чтобы пользовательские агенты на этой стороне могли соответствующим образом восстановиться.

9.4. Одновременные соединения

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

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

Несколько соединений обычно используются для предотвращения проблемы «блокировки начала очереди» (head-of-line blocking), при которой запрос, требующий значительной обработки на стороне сервера и/или передачи очень большого содержимого, блокировал бы последующие запросы в том же соединении. Однако каждое соединение потребляет ресурсы сервера.

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

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

9.5. Сбои и время ожидания

Серверы обычно устанавливают некоторое время ожидания, по истечении которого они перестают поддерживать неактивное соединение. Прокси-серверы могут устанавливать большее значение, поскольку клиент, вероятно, будет устанавливать больше соединений через тот же прокси-сервер. Использование постоянных соединений не устанавливает требований к длительности (или наличию) этого времени ожидания ни для клиента, ни для сервера.

Клиенту или серверу, желающему завершить соединение по истечении времени ожидания, СЛЕДУЕТ (SHOULD) выполнить его корректное закрытие. Реализациям СЛЕДУЕТ (SHOULD) постоянно отслеживать открытые соединения на предмет получения сигнала закрытия и реагировать соответствующим образом, поскольку своевременное закрытие соединения с обеих сторон позволяет освободить выделенные системные ресурсы.

Клиент, сервер или прокси-сервер МОЖЕТ (MAY) закрыть транспортное соединение в любой момент. Например, клиент мог начать отправку нового запроса одновременно с решением сервера закрыть «простаивающее» соединение. С точки зрения сервера соединение закрывается во время простоя, но с точки зрения клиента запрос выполняется.

Серверу СЛЕДУЕТ (SHOULD) по возможности сохранять постоянные соединения и позволять механизмам управления потоком нижележащего транспорта устранять временные перегрузки, а не завершать соединения в расчёте на повторные запросы клиентов. Последний способ может усугубить перегрузку сети или нагрузку на сервер.

Клиенту, отправляющему тело сообщения, СЛЕДУЕТ (SHOULD) во время передачи запроса отслеживать сетевое соединение на предмет ответа с ошибкой. Если клиент видит ответ, указывающий, что сервер не желает получать тело сообщения и закрывает соединение, клиенту СЛЕДУЕТ (SHOULD) немедленно прекратить передачу тела и закрыть свою сторону соединения.

9.6. Закрытие соединения

Параметр соединения «close» определён как сигнал о том, что отправитель закроет это соединение после завершения ответа. Отправителю СЛЕДУЕТ (SHOULD) отправлять поле заголовка Connection (раздел 7.6.1 [HTTP]), содержащее параметр соединения «close», когда он намерен закрыть соединение. Например,

Connection: close

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

Обратите внимание, что имя поля «Close» зарезервировано, поскольку использование этого имени как поля заголовка может конфликтовать с параметром соединения «close».

Клиенту, отправляющему параметр соединения «close», ЗАПРЕЩЕНО (MUST NOT) отправлять дальнейшие запросы по этому соединению (после запроса, содержащего «close»), и он ОБЯЗАН (MUST) закрыть соединение после прочтения окончательного сообщения ответа, соответствующего этому запросу.

Сервер, получивший параметр соединения «close», ОБЯЗАН (MUST) начать закрытие соединения (см. ниже) после отправки окончательного ответа на запрос, содержавший параметр соединения «close». Серверу СЛЕДУЕТ (SHOULD) отправить параметр соединения «close» в своём окончательном ответе по этому соединению. Серверу ЗАПРЕЩЕНО (MUST NOT) обрабатывать любые последующие запросы, полученные по этому соединению.

Сервер, отправляющий параметр соединения «close», ОБЯЗАН (MUST) начать закрытие соединения (см. ниже) после отправки ответа, содержащего параметр соединения «close». Серверу ЗАПРЕЩЕНО (MUST NOT) обрабатывать любые последующие запросы, полученные по этому соединению.

Клиент, получивший параметр соединения «close», ОБЯЗАН (MUST) прекратить отправку запросов по этому соединению и закрыть соединение после прочтения сообщения ответа, содержащего параметр соединения «close»; если по соединению были отправлены дополнительные конвейерные запросы, клиенту НЕ СЛЕДУЕТ (SHOULD NOT) предполагать, что сервер их обработает.

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

Чтобы избежать проблемы сброса TCP, серверы обычно закрывают соединение поэтапно. Сначала сервер выполняет полузакрытие, закрывая только сторону записи двунаправленного соединения. Затем сервер продолжает читать из соединения, пока не получит соответствующее закрытие от клиента или пока не будет достаточно уверен, что его собственный стек TCP получил подтверждение клиента для пакета или пакетов с последним ответом сервера. Наконец, сервер полностью закрывает соединение.

Неизвестно, относится ли проблема сброса исключительно к TCP или может встречаться и в других протоколах транспортного соединения.

Обратите внимание, что TCP-соединение, полузакрытое клиентом, не определяет границу сообщения запроса и не означает, что клиент больше не заинтересован в ответе. В общем случае на транспортные сигналы нельзя полагаться для обозначения пограничных случаев, поскольку HTTP/1.1 не зависит от транспорта.

9.7. Установление соединения TLS

Концептуально HTTP/TLS — это просто отправка сообщений HTTP через соединение, защищённое TLS [TLS13].

Клиент HTTP также выступает клиентом TLS. Он устанавливает соединение с сервером на соответствующем порту и отправляет TLS ClientHello, чтобы начать рукопожатие TLS. После завершения рукопожатия TLS клиент может инициировать первый запрос HTTP. Все данные HTTP ОБЯЗАНЫ (MUST) отправляться как «application data» TLS, но в остальном соединение рассматривается как обычное соединение HTTP (включая возможность повторного использования как постоянного соединения).

9.8. Закрытие соединения TLS

Для безопасного закрытия соединения TLS использует обмен уведомлениями о закрытии перед закрытием соединения, не вызванным ошибкой; см. раздел 6.1 [TLS13]. При получении действительного уведомления о закрытии реализация может быть уверена, что больше не получит данных по этому соединению.

Когда реализация знает, что отправила или получила все интересующие её данные сообщения, обычно благодаря обнаружению границ сообщения HTTP, она может выполнить «неполное закрытие», отправив уведомление о закрытии, а затем закрыв соединение, не дожидаясь соответствующего уведомления о закрытии от другой стороны.

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

При обнаружении неполного закрытия клиенту СЛЕДУЕТ (SHOULD) считать завершёнными все запросы, для которых он получил:

  1. количество данных, указанное в поле заголовка Content-Length, либо
  2. завершающую часть нулевой длины (при использовании Transfer-Encoding со значением chunked).

Ответ, не содержащий ни кодирования передачи chunked, ни Content-Length, является полным только при получении действительного уведомления о закрытии. Если считать неполное сообщение полным, реализации могут подвергнуться атаке.

Клиенту, обнаружившему неполное закрытие, СЛЕДУЕТ (SHOULD) корректно восстановиться.

Клиенты ОБЯЗАНЫ (MUST) отправить уведомление о закрытии перед закрытием соединения. Клиенты, не ожидающие больше данных, МОГУТ (MAY) не ждать уведомления сервера о закрытии и просто закрыть соединение, тем самым вызвав неполное закрытие на стороне сервера.

Серверам СЛЕДУЕТ (SHOULD) быть готовыми получить неполное закрытие от клиента, поскольку клиент часто способен определить конец данных сервера.

Серверы ОБЯЗАНЫ (MUST) попытаться начать обмен уведомлениями о закрытии с клиентом перед закрытием соединения. Серверы МОГУТ (MAY) закрыть соединение после отправки уведомления о закрытии, тем самым вызвав неполное закрытие на стороне клиента.

10. Включение сообщений в качестве данных

10.1. Тип данных message/http

Тип данных «message/http» можно использовать для включения одного сообщения запроса или ответа HTTP при условии соблюдения ограничений MIME для всех типов «message» в отношении длины строк и кодирований. Из-за ограничений длины строк значениям полей внутри «message/http» разрешено использовать перенос строк (obs-fold), как описано в разделе 5.2, для передачи значения поля в нескольких строках. Получатель данных «message/http» ОБЯЗАН (MUST) заменить любой устаревший перенос строк одним или несколькими символами SP при использовании сообщения.

Имя типа
message
Имя подтипа
http
Обязательные параметры
Не применимо
Необязательные параметры
version, msgtype

version: номер HTTP-version вложенного сообщения (например, «1.1»). Если отсутствует, версию можно определить по первой строке тела.

msgtype: тип сообщения — «request» или «response». Если отсутствует, тип можно определить по первой строке тела.

Вопросы кодирования
допускаются только «7bit», «8bit» или «binary»
Вопросы безопасности
см. раздел 11
Вопросы совместимости
Не применимо
Опубликованная спецификация
RFC 9112 (см. раздел 10.1).
Приложения, использующие этот тип данных
Не применимо
Вопросы идентификаторов фрагментов
Не применимо
Дополнительная информация
Сигнатуры: не применимо; устаревшие псевдонимы этого типа: не применимо; расширения файлов: не применимо; коды типа файлов Macintosh: не применимо.
Контактное лицо и адрес электронной почты для дополнительной информации
См. раздел «Адреса авторов».
Предполагаемое использование
COMMON
Ограничения использования
Не применимо
Автор
См. раздел «Адреса авторов».
Орган, контролирующий изменения
IESG

10.2. Тип данных application/http

Тип данных «application/http» можно использовать для включения конвейера из одного или нескольких сообщений запросов или ответов HTTP (не смешанных между собой).

Имя типа
application
Имя подтипа
http
Обязательные параметры
Не применимо
Необязательные параметры
version, msgtype

version: номер HTTP-version вложенных сообщений (например, «1.1»). Если отсутствует, версию можно определить по первой строке тела.

msgtype: тип сообщения — «request» или «response». Если отсутствует, тип можно определить по первой строке тела.

Вопросы кодирования
Сообщения HTTP, включённые этим типом, имеют формат «binary»; при передаче по электронной почте необходимо использовать соответствующее Content-Transfer-Encoding.
Вопросы безопасности
см. раздел 11
Вопросы совместимости
Не применимо
Опубликованная спецификация
RFC 9112 (см. раздел 10.2).
Приложения, использующие этот тип данных
Не применимо
Вопросы идентификаторов фрагментов
Не применимо
Дополнительная информация
Устаревшие псевдонимы этого типа: не применимо; сигнатуры: нет; расширения файлов: не применимо; коды типа файлов Macintosh: не применимо.
Контактное лицо и адрес электронной почты для дополнительной информации
См. раздел «Адреса авторов».
Предполагаемое использование
COMMON
Ограничения использования
Не применимо
Автор
См. раздел «Адреса авторов».
Орган, контролирующий изменения
IESG

11. Вопросы безопасности

Этот раздел предназначен для информирования разработчиков, поставщиков информации и пользователей об известных вопросах безопасности, относящихся к синтаксису и разбору сообщений HTTP. Вопросы безопасности семантики, содержимого и маршрутизации HTTP рассматриваются в [HTTP].

11.1. Разделение ответов

Разделение ответов (также называемое внедрением CRLF) — распространённый приём, используемый в различных атаках при работе с вебом, который эксплуатирует построчный характер определения границ сообщений HTTP и упорядоченное сопоставление запросов с ответами в постоянных соединениях [Klein]. Этот приём может быть особенно разрушительным, когда запросы проходят через общий кэш.

Разделение ответов использует уязвимость серверов (обычно сервера приложений), при которой атакующий может отправить закодированные данные в некотором параметре запроса, которые впоследствии декодируются и отражаются в одном из полей заголовка ответа. Если декодированные данные составлены так, что создаётся впечатление завершения ответа и начала следующего, ответ оказывается разделённым, а содержимое кажущегося второго ответа контролируется атакующим. Затем атакующий может выполнить любой другой запрос по тому же постоянному соединению и обмануть получателей (включая посредников), заставив их считать вторую половину разделённого ответа авторитетным ответом на второй запрос.

Например, параметр в request-target может быть прочитан сервером приложений и повторно использован в перенаправлении, вследствие чего тот же параметр отражается в поле заголовка Location ответа. Если приложение декодирует параметр и неправильно кодирует его при помещении в поле ответа, атакующий может отправить закодированные октеты CRLF и другое содержимое, из-за которых единственный ответ приложения будет выглядеть как два или более ответа.

Распространённая защита от разделения ответов — фильтровать запросы на наличие данных, похожих на закодированные CR и LF (например, «%0D» и «%0A»). Однако это предполагает, что сервер приложений выполняет только декодирование URI, а не менее очевидные преобразования данных, такие как перекодирование набора символов, преобразование сущностей XML, декодирование base64, переформатирование sprintf и т. д. Более эффективная мера — не позволять ничему, кроме основных библиотек протокола сервера, отправлять CR или LF внутри секции заголовка; это означает ограничение вывода полей заголовка интерфейсами API, фильтрующими недопустимые октеты, и запрет серверам приложений напрямую записывать данные в поток протокола.

11.2. Контрабанда запросов

Контрабанда запросов ([Linhart]) — приём, использующий различия в разборе протокола разными получателями для сокрытия дополнительных запросов (которые в иных условиях могли бы блокироваться или запрещаться политикой) внутри внешне безобидного запроса. Как и разделение ответов, контрабанда запросов может приводить к разнообразным атакам на использование HTTP.

Эта спецификация ввела новые требования к разбору запросов, особенно к определению границ сообщений в разделе 6.3, чтобы снизить эффективность контрабанды запросов.

11.3. Целостность сообщений

HTTP не определяет конкретного механизма обеспечения целостности сообщений, вместо этого полагаясь на способность нижележащих транспортных протоколов обнаруживать ошибки и на определение границ по длине или частям для обнаружения полноты. Исторически отсутствие единого механизма целостности оправдывалось неформальным характером большинства взаимодействий HTTP. Однако распространённость HTTP как механизма доступа к информации привела к его всё более широкому использованию в средах, где проверка целостности сообщений имеет решающее значение.

Механизмы, предоставляемые схемой «https», такие как аутентифицированное шифрование, обеспечивают защиту от изменения сообщений. Однако необходимо следить за тем, чтобы закрытие соединения нельзя было использовать для усечения сообщений (см. раздел 9.8). Пользовательские агенты могут отказываться принимать неполные сообщения или обрабатывать их особым образом. Например, браузер, используемый для просмотра истории болезни или информации о взаимодействии лекарств, должен сообщать пользователю, если протокол обнаружил, что такая информация неполна, устарела или повреждена при передаче. Такие механизмы могут избирательно включаться расширениями пользовательского агента или наличием в ответе метаданных целостности сообщения.

Схема «http» не предоставляет защиты от случайного или злонамеренного изменения сообщений.

Расширения протокола можно использовать для снижения риска нежелательного изменения сообщений посредниками даже при использовании схемы «https». Целостность может обеспечиваться с помощью кодов аутентификации сообщений или цифровых подписей, избирательно добавляемых к сообщениям через расширяемые поля метаданных.

11.4. Конфиденциальность сообщений

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

Схему «https» можно использовать для обозначения ресурсов, требующих конфиденциального соединения, как описано в разделе 4.2.2 [HTTP].

12. Вопросы IANA

Орган, контролирующий изменения для следующих регистраций: «IETF (iesg@ietf.org) - Internet Engineering Task Force».

12.1. Регистрация имён полей

IANA добавила следующие имена полей в «Hypertext Transfer Protocol (HTTP) Field Name Registry» по адресу https://www.iana.org/assignments/http-fields, как описано в разделе 18.4 [HTTP].

Таблица 1
Имя поляСтатусРазделКомментарии
Closepermanent9.6зарезервировано
MIME-VersionpermanentB.1
Transfer-Encodingpermanent6.1

12.2. Регистрация типов данных

IANA обновила реестр «Media Types» по адресу https://www.iana.org/assignments/media-types, включив регистрационные сведения из разделов 10.1 и 10.2 для типов данных «message/http» и «application/http» соответственно.

12.3. Регистрация кодирований передачи

IANA обновила «HTTP Transfer Coding Registry» по адресу https://www.iana.org/assignments/http-parameters/, включив процедуру регистрации из раздела 7.3 и имена кодирований содержимого, приведённые в таблице ниже.

Таблица 2
ИмяОписаниеРаздел
chunkedПередача последовательностью частей7.1
compressФормат данных UNIX «compress» [Welch]7.2
deflateСжатые данные «deflate» ([RFC1951]) внутри формата данных «zlib» ([RFC1950])7.2
gzipФормат файлов GZIP [RFC1952]7.2
trailersзарезервировано12.3
x-compressУстарело (псевдоним compress)7.2
x-gzipУстарело (псевдоним gzip)7.2

Примечание. Имя кодирования «trailers» зарезервировано, поскольку его использование конфликтовало бы с ключевым словом «trailers» в поле заголовка TE (раздел 10.1.4 [HTTP]).

12.4. Регистрация идентификатора протокола ALPN

IANA обновила реестр «TLS Application-Layer Protocol Negotiation (ALPN) Protocol IDs» по адресу https://www.iana.org/assignments/tls-extensiontype-values/ следующей записью:

Таблица 3
ПротоколИдентификационная последовательностьСсылка
HTTP/1.10x68 0x74 0x74 0x70 0x2f 0x31 0x2e 0x31 ("http/1.1")RFC 9112

13. Ссылки

13.1. Нормативные ссылки

[CACHING]  Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
              Ed., "HTTP Caching", STD 98, RFC 9111,
              DOI 10.17487/RFC9111, June 2022,
              <https://www.rfc-editor.org/info/rfc9111>.

   [HTTP]     Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
              Ed., "HTTP Semantics", STD 97, RFC 9110,
              DOI 10.17487/RFC9110, June 2022,
              <https://www.rfc-editor.org/info/rfc9110>.

   [RFC1950]  Deutsch, P. and J-L. Gailly, "ZLIB Compressed Data Format
              Specification version 3.3", RFC 1950,
              DOI 10.17487/RFC1950, May 1996,
              <https://www.rfc-editor.org/info/rfc1950>.

   [RFC1951]  Deutsch, P., "DEFLATE Compressed Data Format Specification
              version 1.3", RFC 1951, DOI 10.17487/RFC1951, May 1996,
              <https://www.rfc-editor.org/info/rfc1951>.

   [RFC1952]  Deutsch, P., "GZIP file format specification version 4.3",
              RFC 1952, DOI 10.17487/RFC1952, May 1996,
              <https://www.rfc-editor.org/info/rfc1952>.

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <https://www.rfc-editor.org/info/rfc2119>.

   [RFC5234]  Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
              Specifications: ABNF", STD 68, RFC 5234,
              DOI 10.17487/RFC5234, January 2008,
              <https://www.rfc-editor.org/info/rfc5234>.

   [RFC7405]  Kyzivat, P., "Case-Sensitive String Support in ABNF",
              RFC 7405, DOI 10.17487/RFC7405, December 2014,
              <https://www.rfc-editor.org/info/rfc7405>.

   [RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
              2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
              May 2017, <https://www.rfc-editor.org/info/rfc8174>.

   [TLS13]    Rescorla, E., "The Transport Layer Security (TLS) Protocol
              Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
              <https://www.rfc-editor.org/info/rfc8446>.

   [URI]      Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
              Resource Identifier (URI): Generic Syntax", STD 66,
              RFC 3986, DOI 10.17487/RFC3986, January 2005,
              <https://www.rfc-editor.org/info/rfc3986>.

   [USASCII]  American National Standards Institute, "Coded Character
              Set -- 7-bit American Standard Code for Information
              Interchange", ANSI X3.4, 1986.

   [Welch]    Welch, T., "A Technique for High-Performance Data
              Compression", IEEE Computer 17(6),
              DOI 10.1109/MC.1984.1659158, June 1984,
              <https://ieeexplore.ieee.org/document/1659158/>.

13.2. Информационные ссылки

[HTTP/1.0] Berners-Lee, T., Fielding, R., and H. Frystyk, "Hypertext
              Transfer Protocol -- HTTP/1.0", RFC 1945,
              DOI 10.17487/RFC1945, May 1996,
              <https://www.rfc-editor.org/info/rfc1945>.

   [Klein]    Klein, A., "Divide and Conquer - HTTP Response Splitting,
              Web Cache Poisoning Attacks, and Related Topics", March
              2004, <https://packetstormsecurity.com/papers/general/whitepaper_httpresponse.pdf>.

   [Linhart]  Linhart, C., Klein, A., Heled, R., and S. Orrin, "HTTP
              Request Smuggling", June 2005,
              <https://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf>.

   [RFC2045]  Freed, N. and N. Borenstein, "Multipurpose Internet Mail
              Extensions (MIME) Part One: Format of Internet Message
              Bodies", RFC 2045, DOI 10.17487/RFC2045, November 1996,
              <https://www.rfc-editor.org/info/rfc2045>.

   [RFC2046]  Freed, N. and N. Borenstein, "Multipurpose Internet Mail
              Extensions (MIME) Part Two: Media Types", RFC 2046,
              DOI 10.17487/RFC2046, November 1996,
              <https://www.rfc-editor.org/info/rfc2046>.

   [RFC2049]  Freed, N. and N. Borenstein, "Multipurpose Internet Mail
              Extensions (MIME) Part Five: Conformance Criteria and
              Examples", RFC 2049, DOI 10.17487/RFC2049, November 1996,
              <https://www.rfc-editor.org/info/rfc2049>.

   [RFC2068]  Fielding, R., Gettys, J., Mogul, J., Frystyk, H., and T.
              Berners-Lee, "Hypertext Transfer Protocol -- HTTP/1.1",
              RFC 2068, DOI 10.17487/RFC2068, January 1997,
              <https://www.rfc-editor.org/info/rfc2068>.

   [RFC2557]  Palme, J., Hopmann, A., and N. Shelness, "MIME
              Encapsulation of Aggregate Documents, such as HTML
              (MHTML)", RFC 2557, DOI 10.17487/RFC2557, March 1999,
              <https://www.rfc-editor.org/info/rfc2557>.

   [RFC5322]  Resnick, P., Ed., "Internet Message Format", RFC 5322,
              DOI 10.17487/RFC5322, October 2008,
              <https://www.rfc-editor.org/info/rfc5322>.

   [RFC7230]  Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer
              Protocol (HTTP/1.1): Message Syntax and Routing",
              RFC 7230, DOI 10.17487/RFC7230, June 2014,
              <https://www.rfc-editor.org/info/rfc7230>.

   [RFC8126]  Cotton, M., Leiba, B., and T. Narten, "Guidelines for
              Writing an IANA Considerations Section in RFCs", BCP 26,
              RFC 8126, DOI 10.17487/RFC8126, June 2017,
              <https://www.rfc-editor.org/info/rfc8126>.

Приложение A. Сводная грамматика ABNF

В приведённой ниже сводной грамматике ABNF правила списков раскрыты согласно разделу 5.6.1 [HTTP].

BWS = <BWS, see [HTTP], Section 5.6.3>

   HTTP-message = start-line CRLF *( field-line CRLF ) CRLF [
    message-body ]
   HTTP-name = %x48.54.54.50 ; HTTP
   HTTP-version = HTTP-name "/" DIGIT "." DIGIT

   OWS = <OWS, see [HTTP], Section 5.6.3>

   RWS = <RWS, see [HTTP], Section 5.6.3>

   Transfer-Encoding = [ transfer-coding *( OWS "," OWS transfer-coding
    ) ]

   absolute-URI = <absolute-URI, see [URI], Section 4.3>
   absolute-form = absolute-URI
   absolute-path = <absolute-path, see [HTTP], Section 4.1>
   asterisk-form = "*"
   authority = <authority, see [URI], Section 3.2>
   authority-form = uri-host ":" port

   chunk = chunk-size [ chunk-ext ] CRLF chunk-data CRLF
   chunk-data = 1*OCTET
   chunk-ext = *( BWS ";" BWS chunk-ext-name [ BWS "=" BWS chunk-ext-val
    ] )
   chunk-ext-name = token
   chunk-ext-val = token / quoted-string
   chunk-size = 1*HEXDIG
   chunked-body = *chunk last-chunk trailer-section CRLF

   field-line = field-name ":" OWS field-value OWS
   field-name = <field-name, see [HTTP], Section 5.1>
   field-value = <field-value, see [HTTP], Section 5.5>

   last-chunk = 1*"0" [ chunk-ext ] CRLF

   message-body = *OCTET
   method = token

   obs-fold = OWS CRLF RWS
   obs-text = <obs-text, see [HTTP], Section 5.6.4>
   origin-form = absolute-path [ "?" query ]

   port = <port, see [URI], Section 3.2.3>

   query = <query, see [URI], Section 3.4>
   quoted-string = <quoted-string, see [HTTP], Section 5.6.4>

   reason-phrase = 1*( HTAB / SP / VCHAR / obs-text )
   request-line = method SP request-target SP HTTP-version
   request-target = origin-form / absolute-form / authority-form /
    asterisk-form

   start-line = request-line / status-line
   status-code = 3DIGIT
   status-line = HTTP-version SP status-code SP [ reason-phrase ]

   token = <token, see [HTTP], Section 5.6.2>
   trailer-section = *( field-line CRLF )
   transfer-coding = <transfer-coding, see [HTTP], Section 10.1.4>

   uri-host = <host, see [URI], Section 3.2.2>

Приложение B. Различия между HTTP и MIME

HTTP/1.1 использует многие конструкции, определённые для формата интернет-сообщений [RFC5322] и многоцелевых расширений интернет-почты (MIME) [RFC2045], чтобы позволить передавать тело сообщения в открытом разнообразии представлений и с расширяемыми полями. Однако некоторые из этих конструкций были переосмыслены, чтобы лучше соответствовать потребностям интерактивного взаимодействия, что привело к некоторым различиям в использовании конструкций MIME внутри HTTP. Эти различия были тщательно выбраны для оптимизации производительности двоичных соединений, обеспечения большей свободы использования новых типов данных, упрощения сравнения дат и поддержки распространённых реализаций.

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

B.1. MIME-Version

HTTP не является протоколом, соответствующим MIME. Однако сообщения могут содержать одно поле заголовка MIME-Version для указания версии протокола MIME, использованной при построении сообщения. Использование поля заголовка MIME-Version указывает на полное соответствие сообщения протоколу MIME (как определено в [RFC2045]). Отправители отвечают за обеспечение полного соответствия (где возможно) при экспорте сообщений HTTP в среды со строгим соблюдением MIME.

B.2. Преобразование в каноническую форму

MIME требует преобразования части тела интернет-письма в каноническую форму перед передачей, как описано в разделе 4 [RFC2049], а также представления разрывов строк в содержимом типа «text» посредством CRLF, запрещая использование CR или LF вне последовательностей разрыва строки [RFC2046]. Напротив, для HTTP не имеет значения, используются ли CRLF, одиночный CR или одиночный LF для обозначения разрыва строки внутри содержимого.

Прокси-серверу или шлюзу из HTTP в среду со строгим соблюдением MIME следует преобразовывать все разрывы строк внутри текстовых типов данных в каноническую форму CRLF согласно RFC 2049. Однако обратите внимание, что это может осложняться наличием Content-Encoding и тем, что HTTP позволяет использовать некоторые наборы символов, которые не применяют октеты 13 и 10 для представления CR и LF соответственно.

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

B.3. Преобразование форматов даты

HTTP/1.1 использует ограниченный набор форматов даты (раздел 5.6.7 [HTTP]) для упрощения сравнения дат. Прокси-серверам и шлюзам из других протоколов следует обеспечивать соответствие любого присутствующего в сообщении поля заголовка Date одному из форматов HTTP/1.1 и при необходимости переписывать дату.

B.4. Преобразование Content-Encoding

MIME не включает понятия, эквивалентного полю заголовка Content-Encoding в HTTP. Поскольку оно действует как модификатор типа данных, прокси-серверам и шлюзам из HTTP в протоколы, соответствующие MIME, следует либо изменять значение поля заголовка Content-Type, либо декодировать представление до пересылки сообщения. (Некоторые экспериментальные применения Content-Type для интернет-почты использовали параметр типа данных «;conversions=<content-coding>» для выполнения функции, эквивалентной Content-Encoding. Однако этот параметр не является частью стандартов MIME.)

B.5. Преобразование Content-Transfer-Encoding

HTTP не использует поле MIME Content-Transfer-Encoding. Прокси-серверы и шлюзы из протоколов, соответствующих MIME, в HTTP должны удалять любой Content-Transfer-Encoding до доставки сообщения ответа клиенту HTTP.

Прокси-серверы и шлюзы из HTTP в протоколы, соответствующие MIME, отвечают за обеспечение правильного формата и кодирования сообщения для безопасной передачи по этому протоколу, где «безопасная передача» определяется ограничениями используемого протокола. Такому прокси-серверу или шлюзу следует преобразовывать данные и помечать их соответствующим Content-Transfer-Encoding, если это повышает вероятность безопасной передачи по протоколу назначения.

B.6. MHTML и ограничения длины строк

Реализации HTTP, использующие общий код с реализациями MHTML [RFC2557], должны учитывать ограничения MIME на длину строк. Поскольку HTTP не имеет этого ограничения, HTTP не переносит длинные строки. Сообщения MHTML, передаваемые по HTTP, следуют всем соглашениям MHTML, включая ограничения длины строк и перенос, каноникализацию и т. д., поскольку HTTP передаёт тела сообщений без изменений и, за исключением типа «multipart/byteranges» (раздел 14.6 [HTTP]), не интерпретирует содержимое или любые строки заголовка MIME, которые могут в нём находиться.

Приложение C. Изменения по сравнению с предыдущими RFC

C.1. Изменения по сравнению с HTTP/0.9

Поскольку HTTP/0.9 не поддерживал поля заголовка в запросе, в нём нет механизма поддержки виртуальных узлов на основе имени (выбора ресурса путём анализа поля заголовка Host). Любому серверу, реализующему виртуальные узлы на основе имени, следует отключить поддержку HTTP/0.9. Большинство запросов, выглядящих как HTTP/0.9, на самом деле являются неправильно сформированными запросами HTTP/1.x, возникшими из-за того, что клиент не смог правильно закодировать request-target.

C.2. Изменения по сравнению с HTTP/1.0

C.2.1. Веб-серверы с несколькими адресами

Требования о том, чтобы клиенты и серверы поддерживали поле заголовка Host (раздел 7.2 [HTTP]), сообщали об ошибке при его отсутствии в запросе HTTP/1.1 и принимали абсолютные URI (раздел 3.2), относятся к наиболее важным изменениям, определённым в HTTP/1.1.

Старые клиенты HTTP/1.0 предполагали взаимно однозначное соответствие IP-адресов и серверов; установленного механизма различения сервера, которому предназначен запрос, кроме IP-адреса, на который запрос направлен, не существовало. Поле заголовка Host было введено при разработке HTTP/1.1 и, хотя большинство браузеров HTTP/1.0 быстро его реализовали, ко всем запросам HTTP/1.1 были предъявлены дополнительные требования для обеспечения полного внедрения. На момент написания большинство служб на основе HTTP зависят от поля заголовка Host при определении адресата запросов.

C.2.2. Соединения Keep-Alive

В HTTP/1.0 каждое соединение устанавливается клиентом перед запросом и закрывается сервером после отправки ответа. Однако некоторые реализации поддерживают явно согласуемый вариант постоянных соединений («Keep-Alive»), описанный в разделе 19.7.1 [RFC2068].

Некоторые клиенты и серверы могут желать совместимости с этими прежними подходами к постоянным соединениям, явно согласуя их с помощью поля заголовка запроса «Connection: keep-alive». Однако некоторые экспериментальные реализации постоянных соединений HTTP/1.0 неисправны; например, если прокси-сервер HTTP/1.0 не понимает Connection, он ошибочно перешлёт это поле заголовка следующему серверу по направлению к источнику, что приведёт к зависанию соединения.

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

Поэтому клиентам рекомендуется не отправлять поле заголовка Proxy-Connection ни в каких запросах.

Клиентам также рекомендуется тщательно обдумать использование «Connection: keep-alive» в запросах; хотя оно может включать постоянные соединения с серверами HTTP/1.0, использующим его клиентам потребуется следить за «зависшими» запросами (которые указывают, что клиенту следует прекратить отправлять это поле заголовка), а при использовании прокси-сервера клиентам вообще не следует применять этот механизм.

C.2.3. Введение Transfer-Encoding

HTTP/1.1 вводит поле заголовка Transfer-Encoding (раздел 6.1). Кодирования передачи необходимо декодировать до пересылки сообщения HTTP по протоколу, соответствующему MIME.

C.3. Изменения по сравнению с RFC 7230

Большинство разделов, представляющих цели проектирования, историю, архитектуру, критерии соответствия, управление версиями протокола, URI, маршрутизацию сообщений и поля заголовка HTTP, перенесены в [HTTP]. Настоящий документ сокращён до синтаксиса обмена сообщениями и требований к управлению соединениями, специфичных для HTTP/1.1.

Одиночные CR запрещены вне содержимого. (Раздел 2.2)

Определение ABNF для authority-form изменено: вместо более общего компонента authority URI (в котором port необязателен) используется конкретный формат host:port, требуемый CONNECT. (Раздел 3.2.3)

От получателей требуется предотвращать атаки с контрабандой запросов и разделением ответов при обработке неоднозначного определения границ сообщения. (Раздел 6.1)

В ABNF для расширений chunked вновь введены (нежелательные) пробельные символы вокруг «;» и «=». Пробельные символы были удалены в [RFC7230], но выяснилось, что это изменение нарушает работу существующих реализаций. (Раздел 7.1.1)

Семантика полей трейлера теперь выходит за рамки особенностей кодирования передачи chunked. Алгоритм декодирования chunked (раздел 7.1.3) обновлён, чтобы поощрять хранение и пересылку полей трейлера отдельно от секции заголовка, разрешать объединение с секцией заголовка только в том случае, если получатель знает, что определение соответствующего поля разрешает объединение и определяет его способ, а в противном случае отбрасывать поля трейлера вместо объединения. Часть трейлера теперь называется секцией трейлера для большего соответствия секции заголовка и более чёткого отличия от части тела. (Раздел 7.1.2)

Параметры кодирования передачи с именем «q» не допускаются во избежание конфликтов с использованием рангов в поле заголовка TE. (Раздел 7.3)

Благодарности

См. приложение «Acknowledgements» в [HTTP], которое также относится к настоящему документу.

Указатель

A C D F G H M O R T X

      A

         absolute-form (request-target)  Раздел 3.2.2
         application/http Тип данных  *_Раздел 10.2_*
         asterisk-form (request-target)  Раздел 3.2.4
         authority-form (request-target)  Раздел 3.2.3

      C

         chunked (формат кодирования)  Раздел 6.1; Раздел 6.3
         chunked (кодирование передачи)  *_Раздел 7.1_*
         close  Раздел 9.3; *_Раздел 9.6_*
         compress (кодирование передачи)  *_Раздел 7.2_*
         Connection поле заголовка  Раздел 9.6
         Content-Length поле заголовка  Раздел 6.2
         Content-Transfer-Encoding поле заголовка  Приложение B.5

      D

         deflate (кодирование передачи)  *_Раздел 7.2_*

      F

         Поля
            Close  *_Раздел 9.6, абзац 4_*
            MIME-Version  *_Приложение B.1_*
            Transfer-Encoding  *_Раздел 6.1_*

      G

         Грамматика
            ALPHA  *_Раздел 1.2_*
            CR  *_Раздел 1.2_*
            CRLF  *_Раздел 1.2_*
            CTL  *_Раздел 1.2_*
            DIGIT  *_Раздел 1.2_*
            DQUOTE  *_Раздел 1.2_*
            HEXDIG  *_Раздел 1.2_*
            HTAB  *_Раздел 1.2_*
            HTTP-message  *_Раздел 2.1_*
            HTTP-name  *_Раздел 2.3_*
            HTTP-version  *_Раздел 2.3_*
            LF  *_Раздел 1.2_*
            OCTET  *_Раздел 1.2_*
            SP  *_Раздел 1.2_*
            Transfer-Encoding  *_Раздел 6.1_*
            VCHAR  *_Раздел 1.2_*
            absolute-form  Раздел 3.2; *_Раздел 3.2.2_*
            asterisk-form  Раздел 3.2; *_Раздел 3.2.4_*
            authority-form  Раздел 3.2; *_Раздел 3.2.3_*
            chunk  *_Раздел 7.1_*
            chunk-data  *_Раздел 7.1_*
            chunk-ext  Раздел 7.1; *_Раздел 7.1.1_*
            chunk-ext-name  *_Раздел 7.1.1_*
            chunk-ext-val  *_Раздел 7.1.1_*
            chunk-size  *_Раздел 7.1_*
            chunked-body  *_Раздел 7.1_*
            field-line  *_Раздел 5_*; Раздел 7.1.2
            field-name  Раздел 5
            field-value  Раздел 5
            last-chunk  *_Раздел 7.1_*
            message-body  *_Раздел 6_*
            method  *_Раздел 3.1_*
            obs-fold  *_Раздел 5.2_*
            origin-form  Раздел 3.2; *_Раздел 3.2.1_*
            reason-phrase  *_Раздел 4_*
            request-line  *_Раздел 3_*
            request-target  *_Раздел 3.2_*
            start-line  *_Раздел 2.1_*
            status-code  *_Раздел 4_*
            status-line  *_Раздел 4_*
            trailer-section  Раздел 7.1; *_Раздел 7.1.2_*
         gzip (кодирование передачи)  *_Раздел 7.2_*

      H

         Поля заголовка
            MIME-Version  *_Приложение B.1_*
            Transfer-Encoding  *_Раздел 6.1_*
         строка заголовка  Раздел 2.1
         секция заголовка  Раздел 2.1
         заголовки  Раздел 2.1

      M

         Тип данных
            application/http  *_Раздел 10.2_*
            message/http  *_Раздел 10.1_*
         message/http Тип данных  *_Раздел 10.1_*
         method  *_Раздел 3.1_*
         MIME-Version поле заголовка  *_Приложение B.1_*

      O

         origin-form (request-target)  Раздел 3.2.1

      R

         request-target  *_Раздел 3.2_*

      T

         Transfer-Encoding поле заголовка  *_Раздел 6.1_*

      X

         x-compress (кодирование передачи)  *_Раздел 7.2_*
         x-gzip (кодирование передачи)  *_Раздел 7.2_*

Адреса авторов

Roy T. Fielding (редактор)
Adobe
345 Park Ave
San Jose, CA 95110
United States of America
Email: fielding@gbiv.com
URI: https://roy.gbiv.com/

Mark Nottingham (редактор)
Fastly
Prahran
Australia
Email: mnot@mnot.net
URI: https://www.mnot.net/

Julian Reschke (редактор)
greenbytes GmbH
Hafenweg 16
48155 Münster
Germany
Email: julian.reschke@greenbytes.de
URI: https://greenbytes.de/tech/webdav/

Перевод: RFCNET · rfcnet.ru

Original copyright notice

Неофициальный перевод. При расхождениях см. оригинал.