previous up next index search
Previous: 4.5.6.4 Строгая транспортная безопасность HTTP (HSTS - RFC-6797)    UP: 4.5.6 WWW
    Next: 4.5.6.6 HTTP поверх TLS (RFC-2818)

4.5.6.5 Протокол HTTP/2 (RFC-7540, Hypertext Transfer Protocol Version 2 (M. Belshe, R. Peon, M. Thomson, Ed.)

Семенов Ю.А. (ИТЭФ-МФТИ)
Yu. Semenov (ITEP-MIPT)

1. Введение

Протокол Hypertext Transfer Protocol (HTTP) необыкновенно популярный протокол. Однако, то как HTTP/1.1 использует свой транспорт ([RFC7230], раздел 6) имеет несколько особенностей, которые негативно влияют на работу приложений.

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

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

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

Начало использования HTTP/2 придется на середину 2015 года, относительно широкое применение начнется в начале 2016 года.

Результирующий протокол является более дружественным для сети, так как можно использовать меньшее число TCP-соединений по сравнению с HTTP/1.x. Это понижает конкуренцию с другими потоками и длительными соединениями, что поднимает эффективность использования сетевых возможностей.

Наконец, HTTP/2 за счет размещения в кадрах двоичных сообщений делает обработку сообщений более эффективной.

2. Обзор протокола HTTP/2

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

Базовым модулем протокола HTTP/2 является кадр (раздел 4.1). Каждый тип кадра служит своей цели. Например, кадры HEADERS и DATA образуют основу запросов и откликов HTTP (раздел 8.1); другие кадры, например, WINDOW_UPDATE и PUSH_PROMISE используются для поддержки других функций HTTP/2.

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

Управление потоком и приоретизация гарантирует возможность эффективного мультиплексирования потоков. Управление потоком (раздел 5.2) помогает сделать так, что передаются только данные, которые нужны получателю. Приоретизация (раздел 5.3) гарантирует то, что ограниченные ресурсы направляются, прежде всего, для наиболее важных потоков.

HTTP/2 вводит новые режимы взаимодействия, за счет того, что сервер может продвигать отклики к клиенту (раздел 8.2). Процедура Server push позволяет серверу посылать данные клиенту, в предположении, что они ему нужны, проигрывая в эффективности использования сетевых ресурсов, но получая взамен снижение задержек отклика. Сервер делает это путем формирования запроса, который он посылает как кадр PUSH_PROMISE. Сервер может послать отклик на синтетический запрос через отдельный поток.

Так как поля заголовка HTTP, используемые для соединения, могут содержать большое количество избыточных данных, кадры, которые эти данные содержат, компрессируются (раздел 4.3). Это особенно удобно для стандартных запросов, позволяя помещать в пакет несколько запросов.

2.1. Организация документа

Спецификация HTTP/2 разделена на четыре части:

В то время как некоторые концепции уровня кадров и потоков независимы от HTTP, эта спецификация не определяет полностью уровень кадров.

2.2. Соглашения и терминология

Используются следующие термины:

Клиент:

Оконечная точка, которая инициирует HTTP/2 соединение. Клиенты посылают запросы HTTP и получают HTTP-отклики.

Соединение:

Соединение транспортного уровня между конечными точками.

Ошибка соединения:

Ошибка, которая воздействует на все HTTP/2 соединение.

Оконечная точка:

Клиент или сервер соединения.

Кадр:

Наименьший блок, передаваемый через соединение HTTP/2, состоящий из заголовка и последовательности октетов переменной длины, зависящей от типа кадра.

Партнер:

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

Получатель:

Оконечная точка, получающая кадры.

Отправитель:

Оконечная точка, передающая кадры.

Сервер:

Оконечная точка, которая воспринимает HTTP/2 соединение. Серверы получают запросы HTTP и формируют HTTP-отклики.

Поток:

Двунаправленный поток кадров через HTTP/2 соединение.

Ошибка потока:

Ошибка индивидуального потока HTTP/2.

Наконец, термины "шлюз", "промежуточный узел", "прокси", и "туннель" определены в разделе 2.3 [RFC7230]. Промежуточный узел в разное время работает как клиент или как сервер.

3. Запуск HTTP/2

Соединение HTTP/2 реализуется в рамках протокола прикладного уровня, работающего поверх TCP-соединения ([TCP]). Клиентом является инициатор TCP-соединения.

HTTP/2 использует ту же URI-схему, что "http" и "https", реализуемую в HTTP/1.1. HTTP/2 использует тот же номер порта по умолчанию: 80 для URI http и 443 для URI "https". В результате реализации для запросов типа http://example.org/foo или https://example.com/bar требуется выявление сначала того, поддерживает ли вышестоящий сервер (ближайший партнер, с которым клиент хочет установить соединение), HTTP/2.

Средства поддержки HTTP/2 для URI http и https различны. Выявление URI для "http" описано в разделе 3.2. Выявление URI для "https" URIs описано в разделе 3.3.

3.1. HTTP/2 Идентификация версии

Протокол, описанный в данном документе, имеет два идентификатора.

Строка "h2c" зарезервирована из пространства идентификаторов ALPN, но описывает протокол, который не использует TLS.

Согласование "h2" или "h2c" подразумевает использование семантики транспорта, безопасности, кадров и сообщений, описанных в данном документе.

3.2. Запуск HTTP/2 для URI "http"

Клиент, который посылает запрос URI "http" без предварительного знания о поддержке HTTP/2, следующим шагом использует механизм HTTP Upgrade (раздел 6.7 [RFC7230]). Клиент делает это путем посылки запроса HTTP/1.1, который включает поле заголовка Upgrade с лексемой "h2c". Такой HTTP/1.1 запрос должен включать только одно поле заголовка HTTP2-Settings (раздел 3.2.1).

Например:

GET / HTTP/1.1
     Host: server.example.com
     Connection: Upgrade, HTTP2-Settings
     Upgrade: h2c
     HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>

Запросы, которые содержат поле данных, должны посылаться исключительно до того, как клиент сможет посылать кадры HTTP/2. Это означает, что большой запрос может блокировать использование соединения до завершения своей передачи.

Если важна одновременность исходного запроса с последующими запросами, может использоваться запрос OPTIONS для выполнения обновления до HTTP/2.

Сервер, который не поддержвает HTTP/2, может реагировать на запрос так, как будто заголовок Upgrade отсутствует:

HTTP/1.1 200 OK
     Content-Length: 243
     Content-Type: text/html
 
     ...

Сервер должен игнорировать строку "h2" в поле заголовка Upgrade. Присутствие строки "h2" подразумевает HTTP/2 через TLS, который согласуется, как это описано в разделе 3.3.

Сервер, который поддерживает HTTP/2, воспринимает upgrade с откликом 101 (Switching Protocols). После пустой строки, которая завершает отклик 101, сервер может начать посылку кадров HTTP/2. Эти кадры должны включать отклик на запрос, который запустил Upgrade.

Например:

HTTP/1.1 101 Switching Protocols
     Connection: Upgrade
     Upgrade: h2c
 
     [ HTTP/2 connection ...

Первый HTTP/2 кадр, посланный сервером, должен быть преамбулой соединения (раздел 3.5), состоящей из кадра SETTINGS (раздел 6.5). По получении отклика 101, клиент должен послать преамбулу соединения (раздел 3.5), которая содержит кадр SETTINGS.

Запрос HTTP/1.1, который послан раньше upgrade, приписывается идентификатору потока 1 (см. раздел 5.1.1) со значение приоритета по умолчанию (Раздел 5.3.5). Поток 1 является неявно полузакрытым ("half closed") для клиента по отношению к серверу (см. раздел 5.1), так как запрос завершен как HTTP/1.1 запрос. После инициализации соединения HTTP/2, поток 1 используется для откликов.

3.2.1 Поле заголовка HTTP2-Settings

Запрос, который обновляет HTTP/1.1 до HTTP/2, должен включать в себя одно поле заголовка "HTTP2-Settings". Поле заголовка "HTTP2-Settings" является полем заголовка специфическим для соединения, которое содержит параметры, управляющие соединением HTTP/2.

HTTP2-Settings = token68

Сервер не должен обновлять соединение до HTTP/2, если это поле заголовка отсутствует, или если присутствует более одного заголовка. Сервер не должен посылать это поле заголовка.

Содержимое поля заголовка "HTTP2-Settings" является полем данных кадра SETTINGS (раздел 6.5), закодированным как строка base64url (то есть, URL- и с именем файла, закодированным Base64, как описано в разделе 5 [RFC4648], с отброшенными завершающими символами '='). Процедура ABNF ["Augmented BNF для синтаксической спецификации: ABNF"] для "token68" определена в разделе 2.1 [RFC7235].

Так как обновление только готовится, клиент, посылающий "HTTP2-Settings", должен послать также "HTTP2-Settings", в качестве опции в поле заголовка "Connection", чтобы предотвратить переадресацию (см. раздел 6.1 [RFC7230]).

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

3.3. Введение HTTP/2 для "https" URI

Клиент, который делает запрос на URI "https", использует TLS ["The Transport Layer Security (TLS) Protocol Version 1.2" TLS12] с согласованием расширения протокола прикладного уровня ALPN (Application layer protocol negotiation) [TLS-ALPN].

HTTP/2 поверх TLS использует идентификатор протокола "h2". Идентификатор протокола "h2c" не должен посылаться клиентом или выбираться сервером; идентификатор протокола "h2c" описывает протокол, который не использует TLS.

Так как согласование TLS завершилось, как клиент, так и сервер должны послать преамбулу [preface] (раздел 3.5).

3.4. Начало HTTP/2 с предварительного знакомства

Клиент может узнать, что определенный сервер поддерживает HTTP/2 другим способом. Например, ["HTTP Alternative Services ALT-SVC] описывает механизм анонсирования таких возможностей.

Клиент должен послать преамбулу соединения (раздел 3.5), и затем может немедленно посылать кадры HTTP/2 серверу; серверы могут идентифицировать эти соединения за счет присутствия преамбулы соединения. Это влияет только на установление HTTP/2 соединения с использованием нешифрованного TCP; реализации, которые поддерживают HTTP/2 поверх TLS должны использовать протокол согласования в TLS [TLS-ALPN].

Аналогично, cервер должен послать преамбулу соединения (раздел 3.5).

3.5. Преамбула соединения HTTP/2

В HTTP/2, каждая из оконечных точек должна послать преамбулу соединения в качестве окончательного подтверждения использования протокола и установления начальных параметров для HTTP/2. Клиент и сервер посылают разные преамбулы соединения.

Преамбула соединения клиента начинается с последовательности из 24 октетов, которые в шестнадцатеричной нотации имеют вид:

0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a

Т.е преамбула соединения начинается со строки "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n". За этой последовательностью должен следовать кадр SETTINGS (раздел 6.5), который может быть пустым. Клиент посылает преамбулу соединения сразу по получении отклика 101 Switching Protocols (индицируя успешное обновление), или после прихода первых информационных октетов TLS соединения. Если HTTP/2 соединение стартует при наличии информации о поддержке сервером протокола, преамбула соединения клиента посылается после установления соединения.

Преамбула соединения клиента выбирается так, чтобы для серверов и промежуточных узлов HTTP/1.1 или HTTP/1.0 исключить обработку последующих кадров.

Преамбула соединения сервера состоит из потенциально пустого кадра SETTINGS (раздел 6.5), который должен быть первым кадром, посылаемым сервером через соединение HTTP/2.

Кадры SETTINGS, полученные от партнера в качестве части преамбулы соединения, должны быть подтверждены (смотри раздел 6.5.3) после посылки преамбулы соединения.

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

Клиенты и серверы должны рассматривать некорректную преамбулу соединения как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR. Кадр GOAWAY (раздел 6.8) может быть в этом случае опущен, так как индивидуальная преамбула указывает, что партнер не использует HTTP/2.

4. HTTP-кадры

Когда HTTP/2 соединение установлено, партнеры могут начать обмен кадрами.

4.1. Формат кадра

Все кадры начинаются с фиксированного 9-октетного заголовка, за которым следует поле данных переменной длины.

Рис. 1. Формат кадра

Длина: Длина поля данных, характеризуемая 24-разрядным целым числом без знака. Значения больше 214 (16,384) не должны пересылаться, если только получатель не установил большее значение для SETTINGS_MAX_FRAME_SIZE. 9 октетов заголовка сюда не включаются.

Тип: 8-битовый код типа кадра. Тип кадра определяет формат и семантику кадра. Реализации должны игнорировать и отбрасывать любые кадры с неизвестным типом.

Флаги: 8-битовое поле, зарезервированное для булевых флагов, характеризующих тип кадра.

Семантика присвоения флагов зависит от типа конкретного кадра. Флаги, которые не имеют определенной семантики для конкретного типа кадров, должны игнорироваться, и должны оставаться не установленными (0x0) при отправке.

R: Зарезервированное однобитовое поле. Семантика бита не определена и бит должен оставаться не установленным (0x0) при отправке и должен игнорироваться при получении.

Идентификатор потока:
Идентификатор потока (смотри раздел 5.1.1) представляет собой 31-битовое целое число без знака. Значение 0x0 зарезервировано для кадров, которые ассоциированы с соединением, в противоположность индивидуальному потоку.

Структура и содержимое поля данных кадра зависит полностью от типа кадра.

4.2 Размер кадра

Размер поля данных кадра ограничивается максимальным размером, который получатель анонсирует в SETTINGS_MAX_FRAME_SIZE. Это значение может лежать в диапазоне от 214 (16,384) до 224-1 (16.777.215) октетов включительно.

Все реализации должны быть способны получать и обрабатывать кадры длиной до 214 октетов, плюс 9 октетов заголовка кадра (раздел 4.1). Размер заголовка кадра не включается при указании размера кадра.

Замечание:
Определенные типы кадров, такие как PING (раздел 6.7), имеют дополнительные ограничения на размер поля данных.

Оконечная точка должна послать сообщение FRAME_SIZE_ERROR, если кадр превышает по размеру величину, определенную в SETTINGS_MAX_FRAME_SIZE, любой предел, определенный для кадра данного типа, или он слишком мал, чтобы содержать обязательные данные кадра. Ошибка размера кадра, который может изменить состояния всего соединения должна рассматриваться, как ошибка соединения (раздел 5.4.1); это относится к любому кадру, который содержит блочный заголовок (раздел 4.3) (то есть, HEADERS, PUSH_PROMISE и CONTINUATION), SETTINGS, и к любым кадрам с идентификатором потока 0.

Оконечные точки обязаны использовать все доступное пространство кадра. Реагирование может быть улучшено путем использования кадров, которые меньше чем допустимый максимальный размер. Посылка больших кадров может привести к задержкам времячувствительных кадров (таких как RST_STREAM, WINDOW_UPDATE или PRIORITY), которые в случае блокировки посылки больших кадров могут повлиять на рабочие характеристики системы.

4.3 Компрессия и декомпрессия заголовка

Точно также как и в HTTP/1, поле заголовка в HTTP/2 представляет собой имя с одним или более сопряженными значениями. Оно используется в HTTP-сообщениях запроса и отклика (смотри раздел 8.2). Смотри также RFC-7541 (HPACK: Header Compression for HTTP/2, R. Peon, H. Ruellan, 2015).

Списки заголовков представляют собой набор из нуля или более полей заголовка. При передаче через соединение, список заголовка формируется в блок заголовка, используя HTTP Header Compression [COMPRESSION]. Блок заголовка делится далее на последовательность из одного или более октетов, называемых фрагментами блока заголовка, передаваемых в поле данных кадров HEADERS (раздел 6.2), PUSH_PROMISE (раздел 6.6) или CONTINUATION (раздел 6.10).

Поле заголовка Cookie [COOKIE] обрабатывается системой HTTP-мэпинга (смотри раздел 8.1.2.5).

Принимающая сторона ответственна за объединение фрагментов заголовка, и последующую декомпрессию блока, для восстановления списка заголовка.

Полный блок заголовка состоит из:

Компрессия заголовка зависит от состояния. Для всего соединения используется один контекст компрессии и один контекст декомпрессии. Ошибка декодирования в блоке заголовка должна рассматриваться как ошибка соединения (раздел 5.4.1) типа COMPRESSION_ERROR.

Каждый блок заголовка обрабатывается как дискретный модуль. Блоки заголовка должны передаваться как непрерывная последовательность кадров, без чередования с какими-либо иными кадрами других типов или потоков. Последний кадр в последовательности кадров HEADERS или CONTINUATION имеет установленный флаг END_HEADERS. Последний кадр в последовательности кадров PUSH_PROMISE или CONTINUATION имеет установленный флаг END_HEADERS. Это позволяет блоку заголовка быть логически эквивалентным одному кадру.

Фрагменты блока заголовка могут быть посланы только как поле данных кадров HEADERS, PUSH_PROMISE или CONTINUATION, так как эти кадры несут в себе данные, которые могут модифицировать контекст компрессии, поддерживаемый получателем. Оконечная точка, получающая кадры HEADERS, PUSH_PROMISE или CONTINUATION, должна восстановить блоки заголовка и выполнить декомпрессию, даже если кадры должны быть отброшены. Получатель должен завершить соединение с ошибкой (раздел 5.4.1) типа COMPRESSION_ERROR, если он не декомпрессировал блок заголовка.

5. Потоки и мультиплексирование

"Поток" является независимой двунаправленной последовательностью кадров между клиентом и сервером в рамках HTTP/2 соединения. Потоки имеют несколько важных характеристик:

5.1 Состояния потока

Жизненный цикл потока показан на рисунке 2.

send: оконечная точка посылает этот кадр
recv: оконечная точка получает этот кадр
H: Заголовки кадра (с подразумеваемыми CONTINUATION)
PP: кадр PUSH_PROMISE (с подразумеваемыми CONTINUATION)
ES: флаг END_STREAM
R: кадр RST_STREAM

Рис. 2. Состояния потока

Заметим, что эта диаграмма показывает переходы между состояниями, а также кадры и флаги, которые влияют на данный переход. В этом смысле, кадры CONTINUATION не вызывают смены состояния; они являются частью HEADERS или PUSH_PROMISE, за которыми следуют. Для целей смены состояния, флаг END_STREAM рассматривается как отдельное событие для кадра, где он размещен; кадр HEADERS с установленным флагом END_STREAM может вызвать переход из одного состояния в другое.

Обе оконечные точки имеют субъективное восприятие состояния потока, которое может отличаться при посылке кадров. Оконечные точки не координируют процессы формирования потоков; они создаются независимо каждой из сторон. Негативные последствия несоответствия состояний ограничено для состояния "closed" после посылки RST_STREAM, где кадры могут приходить некоторое время после закрытия.

Потоки имеют следующие состояния:

idle:

Все потоки начинаются из состояния "idle" (пассивен).

В этом состоянии разрешены следующие переходы:

Получение любого кадра, отличного от HEADERS или PRIORITY для потока в этом состоянии должно рассматриваться, как ошибка соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

reserved (локально):

Поток в состоянии "зарезервирован (локально)" создан путем посылки кадра PUSH_PROMISE. Кадр PUSH_PROMISE резервирует поток в пассивном состоянии, путем ассоциации потока с открытым потоком, который был инициирован удаленным партнером (смотри раздел 8.2).

В этом состоянии возможны только следующие переходы:

В этом состоянии оконечная точка не должна посылать какие-либо кадры, отличные от HEADERS, RST_STREAM или PRIORITY.

В этом состоянии может быть получен кадр PRIORITY или WINDOW_UPDATE. Получение любого кадра, отличного от RST_STREAM, PRIORITY или WINDOW_UPDATE в этом состоянии рассматривается как ошибка соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

reserved (удаленно):

Поток в состоянии "reserved (удаленный)" зарезервирован удаленным партнером.

В этом состоянии допустимы только следующие переходы:

В этом состоянии оконечная точка может послать кадр PRIORITY, чтобы реприоретизировать поток. Оконечная точка не должна посылать в этом состоянии какие-либо кадры, отличные от RST_STREAM, WINDOW_UPDATE или PRIORITY.

Получение любого кадра потока, отличного от HEADERS, RST_STREAM или PRIORITY в этом состоянии должно рассматриваться как ошибка соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

open:

Поток в состоянии "open" может использоваться обоими партнерами для посылки кадров любого типа. В этом состоянии посылающие партнеры получают значения предельных параметров потока (раздел 5.2).

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

Любая из оконечных точек в этом состоянии может послать кадры RST_STREAM, вызывая немедленный переход в состояние "closed" (закрыто).

полузакрытый (локально):

Поток, который является "полузакрытым (локально)", не может использоваться для пересылки кадров, отличных от WINDOW_UPDATE, PRIORITY и RST_STREAM.

Переходы потока из этого состояния в состояние "closed" (закрыто) возможно, когда приходит кадр, который содержит флаг END_STREAM, или когда любой из партнеров посылает кадр RST_STREAM.

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

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

полузакрытый (удаленно):

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

Если оконечная точка получает дополнительные кадры для потока, который находится в состоянии, отличном от WINDOW_UPDATE, PRIORITY или RST_STREAM, она должна откликнуться сигналом ошибки потока (раздел 5.4.2) типа STREAM_CLOSED.

Поток, который является "полузакрытым (удаленно)", может использоваться оконечной точкой для посылки кадров любого типа. В этом состоянии оконечная точка продолжает отслеживать анонсированный уровень пределов управления потоком (раздел 5.2).

Поток может перейти из этого состояния в состояние "закрыто" путем посылки кадра, который содержит флаг END_STREAM, или когда любой из партнеров посылает кадр RST_STREAM.

closed:

Состояние "closed" является терминальным состоянием.

Оконечная точка не должна посылать кадры, отличные от PRIORITY, для закрытых потоков. Оконечная точка, которая получает любой кадр, отличный от PRIORITY, после получения RST_STREAM, должна рассматривать его как ошибку потока (раздел 5.4.2) типа STREAM_CLOSED. Аналогично, оконечная точка, которая получает любые кадры после получения кадра с флагом END_STREAM, должна рассматривать это как ошибку соединения (раздел 5.4.1) типа STREAM_CLOSED, если только такой кадр не разрешен, как это описано ниже.

В этом состоянии могут быть получены кадры WINDOW_UPDATE или RST_STREAM вскоре после посылки кадра DATA или HEADERS, содержащего флаг END_STREAM. До тех пор пока удаленный партнер получает и обрабатывает RST_STREAM или кадр, содержащий флаг END_STREAM, он может посылать кадры этого типа. Оконечные точки должны игнорировать кадры WINDOW_UPDATE или RST_STREAM, полученные в этом состоянии, хотя оконечные точки могут решить воспринимать кадры, которые приходят много позже посылки END_STREAM, как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Кадры PRIORITY могут посылаться в закрытые потоки, чтобы приоретизировать потоки, которые являются зависимыми от закрытого потока. Оконечные точки должны обрабатывать кадры PRIORITY, хотя они могут игнорироваться, если поток был удален из дерева зависимостей (смотри раздел 5.3.4).

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

Кадры, управляемые потоком (т.е., DATA) и полученные после отправки RST_STREAM нумеруются в рамках окна управления потоком. Даже если кадры могли игнорироваться, так как они посланы до получения отправителем RST_STREAM, отправитель будет считать эти кадры в пределах окна управления потоком.

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

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

5.1.1 Идентификаторы потока

Потоки идентифицируются с помощью 31-битных целых чисел без знака. Потоки, инициированные клиентом, должны использовать нечетные идентификаторы потока; потоки, инициированные сервером должны использовать четные идентификаторы потока. Идентификатор потока (0x0) используется для сообщений управления соединением; нулевой идентификатор потока не может быть использован для инициации нового потока.

HTTP/1.1 запросы, которые обновлены до HTTP/2 (смотри раздел 3.2) ставятся в соответсвие с идентификатором потока (0x1). После завершения обновления поток 0x1 является для клиента "полузакрытым (локально)". Следовательно, номер 0x1 не может быть выбран клиентом в качестве нового идентификатора потока.

Идентификатор вновь установленного потока должен быть численно больше, чем для всех потоков, созданных или зарезервированных данной оконечной точкой. Это относится к потокам открытым с помощью кадра HEADERS и к потокам, которые зарезервированы с помощью PUSH_PROMISE. Оконечная точка, которая получает неизвестный идентификатор потока, должна реагировать сигналом ошибки соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Первое использование нового идентификатора потока закрывает все потоки с состоянием "idle", которые могли быть инициированы данным партнером с идентификаторами потока, имеющими меньшие значения. Например, если клиент посылает кадр HEADERS в поток 7, не посылая кадр в поток 5, тогда поток 5 переходит в состояние "closed" , когда первый кадр потока 7 оказывается послан и получен.

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

5.1.2 Одновременность потоков

Партнер может ограничить число одновременно активных потоков, используя параметр SETTINGS_MAX_CONCURRENT_STREAMS (смотри раздел 6.5.2) в кадре SETTINGS. Максимальное число одновременных потоков является специфическим для каждой оконечной точки и применимо только для партнера, получившего эту установку. То есть, клиент специфицирует максимальное число одновременных потоков, инициируемых сервером, а серверы специфицируют максимальное число одновременных потоков, инициируемых клиентом.

Потоки, которые находятся в открытом состоянии ("open"), или в любом из "полузакрытых" состояний нумеруются вплоть до максимального числа потоков, позволенных открыть оконечной точке. Потоки в любом из этих трех состояний нумеруются в направлении предела, указанного в SETTINGS_MAX_CONCURRENT_STREAMS. Потоки в любом из резервированных состояний не нумеруются до предельного значения потоков.

Оконечные точки не должны превышать предел, установленный партнером. Оконечная точка, получающая кадр HEADERS, который вызывает превышение предела для ее анонсированного числа одновременных потоков, должна рассматривать это, как ошибку потока (раздел 5.4.2) типа PROTOCOL_ERROR или REFUSED_STREAM. Выбор ошибки кода определяется тем, хочет ли оконечная точка допускать автоматическое повторение попытки, подробности смотри в разделе 8.1.4).

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

5.2 Управления потоком

Использование потоков для мультиплексирования порождает противоречие при использовании TCP-соединения для блокированных потоков. Схема управления потоком гарантирует то, что потоки одного и того же соединения не будут деструктивно взаимодействовать друг с другом. Управление потоком используется как для отдельных потоков, так и для соединения в целом.

HTTP/2 осуществляет управление потоком за счет использования кадра WINDOW_UPDATE (раздел 6.9).

5.2.1 Принципы управления потоком

Управление потоком HTTP/2 имеет целью обеспечение различных алгоритмов управления потоком без изменения протокола. Управление потоком в HTTP/2 имеет следующие характеристики:

  1. Управление потоком является специфическим для соединения. Оба типа управления потоком между оконечными точками канального сегмента (hop), а не через весь маршрут из конца в конец.
  2. Управление потоком базируется на кадрах обновления окна. Получатели анонсируют, сколько октетов они готовы получить для текущего потока и для соединения в целом. Эта схема базируется на доверии.
  3. Управление потоком работает с учетом направления с и обеспечивается получателем. Получатель может выбрать любой размер окна, которые он хочет иметь для каждого потока и для всего соединения. Отправитель должен учитывать пределы управления потоком, установленные получателем. Клиенты, серверы и промежуточные узлы независимо анонсируют свои окна управления потоком как получатели и ожидают значений пределов управления, установленных их партнерами при отправлении пакетов.
  4. Исходное значение для окна управления потоком равно 65,535 октетов для новых потоков и для соединения в целом.
  5. Тип кадра определяет, относится ли управление потоком к кадру. Для кадров, специфицированных в данном RFC, только кадры DATA являются объектами управления потоком; все другие типы кадров не будут занимать места в анонсированном окне управления потоком. Это гарантирует, что важные для управления кадры не будут заблокированы системой управления потока.
  6. Управление потоком не может быть запрещено.
  7. HTTP/2 определяет только формат и семантику кадра WINDOW_UPDATE (раздел 6.9). Данное RFC не оговаривает, как получатель решает, когда посылать этот кадр или значения, которые он несет, здесь не специфицируется, как отправитель выбирает пакеты для отправки. Реализации могут выбрать любой алгоритм, который подходит для их нужд.

Реализации ответственны также за то, как следует посылать запросы и отклики с учетом их приоритета; как избежать блокировки запросов; и управлять формированием новых потоков. Алгоритмы этих выборов могут интерферировать с любыми алгоритмами управления потоком.

5.2.2 Правильное использование управления потоками

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

В ситуациях, которые не требуют этого, можно анонсировать окно управления потока максимального размера (231-1), и сохранять это окно при посылке кадра WINDOW_UPDATE при получении любых данных. Это эффективно исключает управление потоком для этого получателя. Напротив, отправитель всегда зависит от окна управления потоком, анонсированного получателем.

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

Но даже при знании произведения полосы на RTT, реализация управления потоком может быть затруднена. Когда при использовании управления потоком получатель должен считать данные из входного TCP-буфера в оговоренный момент времени. Невозможность выполнить это может привести к проблемам, когда критические кадры, такие как WINDOW_UPDATE, не могут быть считаны.

5.3 Приоритет потока

Клиент может присвоить приоритет новому потоку путем включения приоритетной информации в кадр HEADERS (раздел 6.2), который открывает поток. В любое другое время, кадр PRIORITY (раздел 6.3) может использоваться для изменения приоритета потока.

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

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

Явное присвоение приоритета потоку является началом процесса приоретизации. Это не гарантирует определенного порядка обработки или пересылки для данного потока по отношению к другим потокам. Оконечная точка не может заставить партнера обрабатывать одновременные потоки в определенном порядке с учетом приоритета.

Информация приоретизации в сообщении может быть опущена. До того как какой-либо приоритет будет задан, используются значения по умолчанию (раздел 5.3.5).

5.3.1 Зависимости потоков

Каждому потоку может быть присвоена определенная зависимость от другого потока. Включение зависимости выражает предпочтения при выделении ресурсов определенному потоку.

Поток, который не зависит ни от какого другого потока, получает значение зависимости 0x0. Другими словами, несуществующий поток 0 образует корень дерева.

Поток, который зависит от другого потока, является зависимым потоком. Поток, от которого поток зависит, является родительским потоком. Зависимость от потока, который не входит в дерево зависимостей - такой как поток в состоянии "idle" - приводит к тому, что потоку присваивается приоритет по умолчанию (раздел 5.3.5).

При установлении зависимости от другого потока, поток добавляется в качестве новой зависимости родительского потока. Зависимые потоки, которые имеют общего прародителя остаются неупорядоченными по отношению друг к другу. Например, если потоки B и C являются зависимыми от потока А, и, если поток D создан зависимым от потока A, это приводит в результате к порядку зависимости потока A, за которым следуют B, C, и D в любом порядке.

Рис. 3. Пример формирования зависимости по-умолчанию

Эксклюзивный флаг позволяет ввeсти новый уровень зависимостей. Эксклюзивный флаг заставляет поток стать зависимым от родительского потока, заставляя другие зависимости стать зависимыми от эксклюзивного потока. В предыдущем примере, если поток D создан с эксклюзивной зависимостью от потока A, это приводит к тому, что D становится зависимым от B и C.

Рис. 4. Пример формирования эксклюзивной зависимости

В пределах дерева зависимостей, зависимый поток должен выделять ресурсы, если все потоки, от которых он зависит (цепочка родительских потоков вплоть до 0x0) либо закрыты, либо их развитие невозможно.

Поток не может зависеть от самого себя. Конечный узел должен рассматривать это как ошибку потока (раздел 5.4.2) типа PROTOCOL_ERROR.

5.3.2 Веса зависимости

Всем зависимым потокам присваиваются целочисленные веса между 1 и 256 (включительно).

Потоки, порожденные одним родителем должны выделять ресурсы согласно определенным весам. Таким образом, если поток B зависит от потока A с весом 4, и C зависит от потока A с весом 12, и если ничего сделать с потоком А невозможно, поток B получит одну треть ресурса, выделенного для потока C.

5.3.3 Реприоретизация

Приоритеты потоков меняются с помощью кадра PRIORITY. Установка зависимости вынуждает поток стать зависимым от заданного родительского потока.

Зависимые потоки следуют за своими родительскими потоками, если приоритет родителя изменяется. Установка зависимости с помощью эксклюзивного флага для реприоретизированного потока делает все зависимости нового родительского потока зависимыми от преприоретизированного потока.

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

Например, рассмотрим исходное дерево зависимостей, где B и C зависят от A, D, и E зависят от C, а F зависит от D. Если A сделано зависимым от D, тогда D занимает место A. Все другие отношения зависимости остаются теми же, за исключением для F, который становится зависимым от A, если реприоретизация эсклюзивна.

Рис. 5. Пример изменения порядка зависимости

5.3.4 Управление состоянием приоритета

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

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

Например, предположим, потоки A и B имеют общего прародителя, а потоки C и D оба зависят от потока A. До удаления потока A, если потоки A и D не могут продолжаться, тогда поток C получает все ресурсы, выделенные потоку A. Если поток A удален из дерева зависимостей, вес потока A делится между потоками C и D. Если поток D все еще не может работать, это приводит к тому, что поток C получает уменьшенную долю ресурсов. Для равных начальных весов C получает одну треть, а не половину имеющихся ресурсов.

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

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

Аналогично, потокам, которые находятся в состоянии "idle", могут быть присвоены приоритеты или они могут стать прародителями других потоков. Это позволяет при создании группировки узлов дерева зависимости сформировать более гибкую систему приоритетов. Пассивные потоки имеют в начале приоритет по умолчанию (раздел 5.3.5).

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

Число дополнительных ресурсов, поддерживаемых оконечной точкой для приоретизации может зависеть от загрузки; при высокой загрузке, приоретизационное состояние может быть аннулировано, чтобы ограничить потребность в ресурсах. В крайних случаях, оконечная точка может даже аннулировать состояние приоретизации для активных и зарезервированных потоков. Если применено ограничение, оконечные точки должны поддерживать состояние, по крайней мере стольких потоков, сколько допускается SETTINGS_MAX_CONCURRENT_STREAMS. Реализации должны также пытаться сохранить состояние для потоков дерева зависимостей, которые активно используются.

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

5.3.5 Приоритеты по умолчанию

Всем потокам изначально присвоена не эксклюзивная зависимость потока 0x0. Потоки Pushed (раздел 8.2) в исходном состоянии зависят от своих ассоциированных потоков. В обоих случаях, потокам присваивается значение веса по умолчанию 16.

5.4 Обработка ошибок

HTTP/2 допускает два класса ошибок:

Список кодов ошибок представлен в разделе 7.

5.4.1 Обработка ошибок соединения

Ошибкой соединения является любая ошибка, которая препятствует дальнейшей обработке на уровне кадров, или которая разрушает любое состояние соединения.

Оконечная точка, которая сталкивается с ошибкой соединения, должна сначала послать кадр GOAWAY (раздел 6.8) с идентификатором последнего потока, который был успешно получен партнером. Кадр GOAWAY содержит код ошибки, который указывает, почему соединение было разорвано. После посылки кадра GOAWAY оконечная точка должна закрыть TCP-соединение.

Возможно, что GOAWAY не будет получен принимающей оконечной точкой (смотри [RFC7230], раздел 6.6). В случае ошибки соединения, GOAWAY пытается взаимодействовать с партнером, чтобы выяснить причину, почему соединение было разорвано.

Оконечная точка может прервать соединение в любое время. В частности, оконечная точка может воспринять ошибку потока, как ошибку соединения. Оконечные точки должны посылать кадр GOAWAY, при завершении соединения, уведомляя о сложившихся обстоятельствах.

5.4.2 Обработка ошибок потока

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

Оконечная точка, которая детектирует ошибку потока, посылает кадр RST_STREAM (раздел 6.4), который содержит идентификатор потока, где произошла ошибка. Кадр RST_STREAM содержит код ошибки, который указывает на тип ошибки.

RST_STREAM является последним кадром, который оконечная точка может послать в поток. Партнер, который посылает кадр RST_STREAM должен быть готов получить любой кадр, который был послан или запрошен для отправки удаленным партнером. Эти кадры могут игнорироваться за исключением случаев, когда они модифицируют состояние соединения (например, для компрессии заголовков (раздел 4.3), или управления потоком).

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

Оконечная точка не должна посылать RST_STREAM в ответ на кадр RST_STREAM, чтобы избежать зацикливания.

5.4.3 Завершение соединения

Если TCP-соединение закрыто или выполнена команда reset (сброс), когда поток остается в открытом или полузакрытом состояниях, не должна автоматически реализовываться процедура повторной попытки (подробности смотри в разделе 8.1.4).

5.5 Расширение HTTP/2

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

Это относится к элементам протокола, определенным в данном документе. Это не распространяется на существующие опции для HTTP, такие как определения методов, статусных кодов или полей заголовка.

Расширения допускают использование новых типов кадров (раздел 4.1), новых установок (раздел 6.5.2), или новых кодов ошибок (раздел 7). Расширения по указанным темам можно найти в разделах: типы кадров (раздел 11.2), установки (раздел 11.3) и коды ошибок (раздел 11.4).

Реализации должны игнорировать неизвестные и неподдерживаемые значения всех расширяемых элементов протокола. Реализации должны отбрасывать кадры неизвестного и неподдерживаемого типа. Это означает что кадры расширения, которые появляются в середине блока заголовка (раздел 4.3) недопустимы; они должны рассматриваться как ошибка соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Расширения, которые могут изменить семантику компонентов существующего протокола должны быть согласованы до начала использования. Например, расширение, которое изменяет структуру кадра HEADERS, не может быть использовано до согласования с партнером. В этом случае может быть также необходимо координировать момент, когда такая модификация вступает в силу.

6. Определения кадра

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

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

6.1 Данные

Кадры DATA (тип=0x0) передают произвольную последовательность октетов, ассоциированную с потоком. Один или более кадров DATA используется, например, для передачи запросов или откликов HTTP.

Кадры DATA могут также содержать заполнитель (padding). Заполнитель может быть добавлен в кадр DATA, чтобы модифицировать размер сообщений. Функции заполнителя при обеспечении безопасности смотри в разделе 10.7.

Рис. 6. Поле данных кадра DATA

Поле данных кадра DATA содержит следующие поля:

Длина заполнителя:

8-битное поле, содержащее длину заполнителя кадра в октетах. Это поле является условным и присутствует, только если флаг PADDED установлен.

Data:

Прикладные данные. Количество данных определяется остатком поля данных кадра после вычитания длины других имеющихся полей.

Заполнитель:

Октеты заполнителя, которые не содержат никакой прикладной информации. При отправке октеты заполнителя должны быть сделаны равными нулю. Получатель не обязан верифицировать заполнитель, но может рассматривать ненулевой заполнитель, как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR.Кадр DATA определяет следующие флаги:

END_STREAM (0x1):

Бит 0, если установлен, указывает. что кадр является последним, который оконечная точка пошлет в идентифицированный поток. Установка этого флага заставляет поток перейти в "полузакрытое" или "закрытое" состояние (раздел 5.1).

PADDED (0x8):

Бит 3, установленный равным 1, указывает, что поле длина заполнителя (Pad Length) и сам заполнитель присутствуют.

Кадры DATA должны быть ассоциированы с потоком. Если кадр DATA получен с полем идентификатора 0x0, получатель должен реагировать на него сигналом ошибки соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Кадры DATA являются объектами управления потоком и могут быть посланы только, когда поток находится в состоянии "open" или "полузакрыт (удаленно)". Все поле данных кадра DATA включается управление потоком, включая поля длина заполнителя и Заполнитель, если они присутствуют. Если кадр DATA получен для потока, который находится не в состоянии "open" или "полузакрыт (локально)", получатель должен рассматривать это, как ошибку потока (раздел 5.4.2) типа STREAM_CLOSED.

Общее число октетов заполнителя определяется значением полы Длина заполнителя. Если длина заполнителя оказалась равной или больше длины поля данных, получатель должен рассматривать это, как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Замечание:

Размер кадра может быть увеличен на один октет за счет добавления поля длина заполнителя со значение нуль.

6.2. Заголовки

Кадр HEADERS (тип=0x1) используется для открытия потока (раздел 5.1), и дополнительно несет в себе фрагмент блока заголовка. Кадры HEADERS могут быть посланы в поток, состояние которого "open" или "полузакрыт (удаленно)".

Рис. 7. Форматы заголовков поля данных

Поле данных кадра HEADERS имеет следующие поля:

Длина заполнителя:

8-битовое поле, содержащее длину заполнителя в октетах. Это поле присутствует, только если установлен флаг PADDED.

E:

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

Зависимость потока:

31-битовый идентификатор потока, от которого зависит этот поток, смотри раздел 5.3. Это поле присутствует, если установлен флаг PRIORITY.

Вес:

8-битовое целое число без знака, определяющее вес приоритета потока, смотри раздел 5.3. Добавляет единицу, чтобы получить значение веса в интервале 1 - 256. Это поле присутствует, если установлен флаг PRIORITY.

Фрагмент блока заголовка (Header Block Fragment):

Фрагмент блока заголовка (раздел 4.3).

Заполнитель:

Октеты заполнителя.

Кадр HEADERS определяет следующие флаги:

END_STREAM (0x1):

Бит 0 =1 индицирует, что блок заголовка (раздел 4.3) является последним, который пошлет оконечная точка в идентифицированный поток.

Кадр HEADERS несет в себе флаг END_STREAM, который сигнализирует о конце потока. Однако, за кадром HEADERS с установленным флагом END_STREAM могут следовать кадры CONTINUATION того же самого потока. Логически, кадры CONTINUATION являются частью кадра HEADERS.

END_HEADERS (0x4):

Бит 2 =1 указывает, что этот кадр содержит весь блок заголовка (раздел 4.3) и за ним не следуют кадры CONTINUATION.

За кадром HEADERS без установленного флага END_HEADERS должен следовать кадр CONTINUATION для того же потока. Получатель должен рассматривать получение кадра любого другого типа или кадра другого потока, как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

PADDED (0x8):

Бит 3 =1 индицирует, что присутствует поле длины заполнителя и какой-то заполнитель.

PRIORITY (0x20):

Бит 5 =1 индицирует, что присутствуют поля Exclusive Flag (E), Stream Dependency, и Weight; смотри раздел 5.3.

Поле данных кадра HEADERS содержит фрагмент блока заголовка (раздел 4.3). Блок заголовка, который не подходит к кадру HEADERS, продолжается в кадре CONTINUATION (раздел 6.10).

Кадры HEADERS должны быть ассоциированы с потоком. Если получен кадр HEADERS, чей идентификатор потока равен 0x0, получатель должен реагировать сигналом ошибки соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Кадр HEADERS изменяет состояние соединения, как это описано в разделе 4.3.

Кадр HEADERS может содержать заполнитель. Поля заполнителя и флаги аналогичны тем, что определены для кадров DATA (раздел 6.1).

Информация приоретизации в кадре HEADERS логически эквивалентна отдельному кадру PRIORITY, но включение в HEADERS исключает потенциальное перемешивание приоретизации, когда создается новый поток. Поля приоретизации в кадрах HEADERS, следующих за первым в потоке, реприоретизуют поток (раздел 5.3.3).

6.3 Приоритет

Кадр PRIORITY (тип=0x2) специфицирует анонсированный отправителем приоритет потока (раздел 5.3). Он может быть послан в любой момент в любой поток, включая потоки idle или closed.

Рис. 8. Поле данных кадра PRIORITY

Поле данных кадра PRIORITY содержит следующие поля:

E:

Однобитный флаг указывает на эксклюзивную зависимость потока, смотри раздел 5.3.

Зависимость потока:

31-битовый идентификатор потока, от которого поток зависит, смотри раздел 5.3.

Вес:

8-битовое целое число без знака, представляющее вес приоритета для потока, смотри раздел 5.3. Добавим единицу к величине, чтобы получить вес в интервале между 1 и 256. Кадр PRIORITY не определяет никаких флагов.

Кадр PRIORITY всегда идентифицирует поток. Если кадр PRIORITY получен с идентификатором 0x0, получатель должен откликнуться сигналом ошибки соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Кадр PRIORITY может быть послан в поток в любом состоянии, хотя он не может быть послан между последовательными кадрами, которые образуют один блок заголовка (раздел 4.3). Заметим, что этот кадр может прийти после обработки или когда посылка кадра завершилась, что не повлияет на идентифицированный поток. Для потока, который находится в "полузакрытом (удаленно)" или "closed" - состоянии, этот кадр может повлиять на обработку идентифицированного потока и потоков от него зависимых, но не на передачу кадра в поток.

Кадр PRIORITY может быть послан для потока в состояниях "idle" или "closed". Это позволяет осуществить реприоретизацию группы зависимых потоков путем модификации приоритета неиспользуемых или закрытых родительских потоков.

Кадр PRIORITY с длиной отличной от 5 октетов должен рассматриваться как ошибка потока (раздел 5.4.2) типа FRAME_SIZE_ERROR.

6.4 RST_STREAM

Кадр RST_STREAM (тип=0x3) позволяет осуществить немедленное завершение потока. RST_STREAM посылается, чтобы завершить поток, или чтобы индицировать факт ошибки.

Код ошибки (32)

Рис. 9. Поле данных кадра RST_STREAM

Кадр RST_STREAM содержит одно 32 битное целое число без знака, определяющее код ошибки (раздел 7). Код ошибки указывает, почему следует прервать поток.

Кадр RST_STREAM не определяет каких-либо флагов.

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

Кадры RST_STREAM должны быть ассоциированы с потоком. Если получен кадр RST_STREAM с идентификатором потока 0x0, получатель должен рассматривать это, как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Кадры RST_STREAM не должны посылаться для потоков с состоянием "idle". Если кадр RST_STREAM указывает на пассивный поток, получатель должен рассматривать это как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Кадр RST_STREAM с длиной, отличной от 4 октетов должен рассматриваться как ошибка соединения (раздел 5.4.1) типа FRAME_SIZE_ERROR.

6.5 SETTINGS (Установки)

Кадр SETTINGS (тип=0x4) переносит конфигурационные параметры, которые определяют то, как оконечная точка передает данные. Кадр SETTINGS используется также подтверждения получения этих параметров. Отдельный параметр SETTINGS может называться "установка" (setting).

Параметры SETTINGS не являются согласуемыми; они описывают характеристики отправителя, которые используются получателем. Различные значения для одного и того же параметра могут быть анонсированы каждым из партнеров. Например, клиент может установить высокое начальное значение ширины окна управление потоком, в то время как сервер может установить более низкое значения с целью экономии ресурсов.

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

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

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

ACK (0x1):

Бит 0 =1 индицирует, что этот кадр подтверждает получение кадра SETTINGS партнером. Когда этот бит установлен, поле данных кадра SETTINGS должно быть пустым. Получение кадра SETTINGS с флагом ACK=1 и значением поля длины отличным от 0 должно рассматриваться как ошибка соединения (раздел 5.4.1) типа FRAME_SIZE_ERROR. Кадры SETTINGS всегда относятся к соединению, и никогда к отдельному потоку. Идентификатор потока для кадра SETTINGS должен быть равен (0x0). Если оконечная точка получает кадр SETTINGS, чей идентификатор потока не равен 0x0, оконечная точка должна сигнализировать об ошибке соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Кадр SETTINGS влияет на состояние соединения. Неверно сформатированный или неполный кадр SETTINGS должен считаться ошибкой соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Кадр SETTINGS с длиной не кратной 6 октетам должен рассматриваться как ошибка соединения (раздел 5.4.1) типа FRAME_SIZE_ERROR.

6.5.1 Формат SETTINGS

Поле кадра SETTINGS состоит из нуля или более параметров, каждый из которых состоит из 16-битового идентификатора установки и 32-битового целого значения без знака.

Рис. 10. Формат Setting

6.5.2 Определенные параметры SETTINGS

Определены следующие параметры:

SETTINGS_HEADER_TABLE_SIZE (0x1):

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

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

SETTINGS_ENABLE_PUSH (0x2):

Эта установка может использоваться, чтобы заблокировать push сервера (раздел 8.2). Оконечная точка не должна посылать кадр PUSH_PROMISE, если он получает этот параметр равный нулю.

Оконечная точка, которая имеет этот параметр =0 так и его подтверждение, должна рассматривать получение кадра PUSH_PROMISE как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Исходное значение равное 1, указывает, что сервер push разрешено. Любое значение отличное от 0 или 1 должно считаться ошибкой соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

SETTINGS_MAX_CONCURRENT_STREAMS (0x3):

Указывает максимальное число одновременных потоков, которое допускает отправитель. Этот предел относится к одному направлению: он относится к числу потоков, которое отправитель разрешает создать получателю. В исходный момент на это значение не накладывается никаких ограничений. Рекомендуется, чтобы эта величина была меньше 100.

Значение 0 для SETTINGS_MAX_CONCURRENT_STREAMS SHOULD не следует рассматривать специфическим для оконечных точек. Нулевое значение предотвращает создание новых потоков, однако это может случиться при любом пределе, если активное число потоков достигает этого уровня. Серверы должны устанавливать нулевое значение на ограниченное время, если сервер не хочет принимать запросы, закрытие соединения является более разумным решением.

SETTINGS_INITIAL_WINDOW_SIZE (0x4):

Индицирует начальную ширину окна отправителя (в октетах) для уровня управления потоком. Начальное значение равно 216-1 (65,535) октетов.

Эта установка влияет на размер окна всех потоков, смотри раздел 6.9.2.

Значения выше максимума размера окна управления потоком 231-1 должно рассматриваться как ошибка соединения (раздел 5.4.1) типа FLOW_CONTROL_ERROR.

SETTINGS_MAX_FRAME_SIZE (0x5):

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

Исходное значение равно 214 (16,384) октетов. Значение, анонсированное оконечной точкой, должно лежать между исходным значением и максимумом допускаемого размером кадра (224-1 или 16.777.215 октетов), включительно. Значения вне этого диапазона должны считаться ошибкой соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

SETTINGS_MAX_HEADER_LIST_SIZE (0x6):
Эта установка информирует партнера о максимальном размере списка заголовков, которые отправитель готов принять, в октетах. Значение базируется на некомпрессированном размере полей заголовка, включая длину имени и значение в октетах плюс дополнительно 32 октета для каждого поля заголовка.

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

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

6.5.3 Синхронизация установок (Settings)

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

Значения в кадре SETTINGS должны быть обработаны в порядки их появления, без обработки каких-либо других кадров между приходящими значениями. Неподдерживаемые параметры должны игнорироваться. Как только все значение обработаны, получатель должен немедленно послать кадр SETTINGS с флагом ACK. После получения кадра SETTINGS с установленным флагом ACK, отправитель измененного параметра может полагаться на то, что установка используется.

Если отправитель кадра SETTINGS не получает подтверждения в пределах разумного времени, он может выдать сигнал ошибки соединения (раздел 5.4.1) типа SETTINGS_TIMEOUT.

6.6 PUSH_PROMISE

Кадр PUSH_PROMISE (тип=0x5)используется для оповещения оконечной точки партнера заранее о намерении отправителя инициировать поток. Кадр PUSH_PROMISE включает 31-битовый идентификатор потока, который оконечная точка планирует создать вместе с набором параметров, которые создают дополнительный контекст потока. Раздел 8.2 содержит описание использования кадров PUSH_PROMISE.

Рис. 11. Формат поля данных PUSH_PROMISE

Поле данных кадра PUSH_PROMISE содержит следующие поля:

Pad Length:

8-битное поле, содержащее длину заполнителя кадра в октетах. Это поле присутствует, если установлен флаг PADDED.

R:
Зарезервированный бит.

Идентификатор будущего (Promised) потока:
31-битное целое число без знака, которое идентифицирует поток, который зарезервирован PUSH_PROMISE. Идентификатор будущего потока должен быть приемлемым для следующего потока, посылаемого отправителем (о новом идентификаторе потока смотри (раздел 5.1.1)).

Фрагмент блока заголовка:
Фрагмент блока заголовка (раздел 4.3), содержащий поля заголовка запроса.

Заполнитель:
Октеты заполнителя.

Кадр PUSH_PROMISE определяет следующие флаги:

END_HEADERS (0x4):
Бит 2 =1 указывает, что данный кадр содержит полный блок заголовка (раздел 4.3) и за ним не следуют кадры CONTINUATION.

За кадром PUSH_PROMISE без установленного флага END_HEADERS должен следовать кадр CONTINUATION того же потока. Получатель должен рассматривать Получение любого другого типа кадра или кадра другого потока как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

PADDED (0x8):
Бит 3 =1 индицирует, что поле длины заполнителя и заполнитель, который он описывает, имеются.

Кадры PUSH_PROMISE должны быть ассоциированы с потоком, инициированным партнером, который находится либо в "открытом" либо "полузарытом (удаленно)" состоянии. Идентификатор потока кадра PUSH_PROMISE индицирует поток, с которым он ассоциирован. Если поле идентификатора потока содержит 0x0, получатель должен реагировать сигналом ошибки соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Будущие (Promised) потоки не обязательно должны следовать в порядке, в котором они анонсированы. PUSH_PROMISE резервирует идентификаторы потока для будущего применения.

PUSH_PROMISE не должен посылаться, если установка SETTINGS_ENABLE_PUSH оконечной точки партнера =0. Оконечная точка, которая имеет такую установку и получила подтверждение, должна рассматривать получение кадра PUSH_PROMISE как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Получатели кадров PUSH_PROMISE могут решить отклонить будущий (promised) поток, прислав отправителю PUSH_PROMISE кадр RST_STREAM с идентификатором будущего потока.

Кадр PUSH_PROMISE модифицирует состояние соединения двумя путями. Во-первых, включением блока заголовка (раздел 4.3) потенциально модифицирует состояние, поддерживаемое для компрессии заголовка. Во-вторых, PUSH_PROMISE резервирует также поток для будущего использования, принуждая будущий (promised) поток перейти в состояние "reserved". Отправитель не должен посылать PUSH_PROMISE, если только поток не является либо "open" либо "полузакрытым (удаленно)"; отправитель должен гарантировать, что будущий поток адекватен новому идентификатору потока (раздел 5.1.1) (то есть, будущий поток должен быть в состоянии "idle").

Так как PUSH_PROMISE резервирует поток, игнорирование кадра PUSH_PROMISE вызовет переход потока в промежуточное состояние. Получатель должен рассматривать получение PUSH_PROMISE, который находится ни в состоянии "open", ни "полузакрыт (локально)", как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR. Однако, оконечная точка, которая послала RST_STREAM в ассоциированный поток, должна обрабатывать кадры PUSH_PROMISE, которые могли быть сформированы до получения и обработки кадра RST_STREAM.

Получатель должен рассматривать получение PUSH_PROMISE, который обещает нелегальный идентификатор потока (раздел 5.1.1) (то есть, идентификатор для потока, который в данный момент находится не в состоянии "idle") как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Кадр PUSH_PROMISE может содержать заполнитель. Поля заполнителя и флаги идентичны тем, что определены для кадров DATA (раздел 6.1).

6.7 PING

Кадр PING (тип=0x6) является механизмом измерения минимального RTT от отправителя, а также как средство определения, является ли пассивное (idle) состояние функциональным. Кадры PING могут посылаться любой оконечной точкой.


Скрытые данные (64)
 

Рис. 12. Формат поля данных PING

В дополнение к заголовку кадра, кадры PING должны содержать 8 октетов поля данных. Отправитель может включить любую величину, которую он выберет и использовать эти октеты любым образом.

Получатели кадра PING, который не включает флага ACK, должны посылать в качестве отклика кадр PING с установленным флагом ACK, и идентичным полем данных. Откликам PING следует присвоить более высокий приоритет, чем любому другому кадру.

Кадр PING определяет следующие флаги:

ACK (0x1):
Бит 0 =1 указывает, что этот кадр PING является откликом. Оконечная точка должна установить этот флаг в отклике PING. Оконечная точка посылать отклики на кадры, содержащие этот флаг. Кадры PING не ассоциируются ни с каким из индивидуальных потоков. Если кадр PING получен со значение поля идентификатора потока отличным от 0x0, получатель должен реагировать сигналом ошибки соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Получение кадра PING со значение поля длины, отличным от 8 должны рассматриваться как ошибка соединения (раздел 5.4.1) типа FRAME_SIZE_ERROR.

6.8 GOAWAY

Кадр GOAWAY (тип=0x7) информирует удаленного партнера прекратить генерацию потоков для данного соединения. GOAWAY может быть послан как клиентом так и сервером. После посылки этого кадра отправитель будет игнорировать кадры, посланные в любой новый поток с идентификатором выше, чем идентификатор последнего потока. Получатели кадра GOAWAY не должны открывать новые потоки в соединении, хотя могут быть организованы новые соединения для новых потоков.

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

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

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

Оконечная точка может решить закрыть соединение без посылки GOAWAY для партнеров, ведущих себя некорректно.

Рис. 13. Формат поля данных GOAWAY

Кадр GOAWAY не определяет никаких флагов.

Кадр GOAWAY относится к соединению, а не определенному потоку. Оконечная точка должна рассматривать кадр GOAWAY с идентификатором потока отличным от 0x0 как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

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

Замечание:

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

В потоках с меньшими или равными идентификаторами, которые не были полностью закрыты до закрытия соединения, не возможны повторные запросы или любая протокольная активность, за исключением идемпотентных действий типа HTTP GET, PUT, или DELETE. Любая протокольная активность, которая использует потоки с более высокими номерами, может быть безопасно возобновлена через новое соединение.

Активность в потоке с номером ниже или равным идентификатору последнего потока может быть успешно завершена. Отправитель кадра GOAWAY может успешно завершить соединение, послав кадр GOAWAY, поддерживая соединение в открытом состоянии вплоть до момента завершения всех процессов потока.

Оконечная точка может послать несколько кадров GOAWAY, если обстоятельства изменяются. Например, оконечная точка, которая посылает GOAWAY с NO_ERROR во время стандартного shutdown, может столкнуться с условием, которое требует немедленного завершения соединения/ Идентификатор последнего потока из последнего полученного кадра GOAWAY указывает, к какому потоку это должно относиться. Оконечные точки не должны увеличивать значения, которые они пересылали в последнем идентификаторе потока, так как партнеры могли перезапустить необработанные запросы через другое соединение.

Клиент, который не может повторить запрос, теряет все запросы, которые находятся в процессе обработки, когда сервер закрывает соединение. Это особенно верно для промежуточных устройств, которые могут не быть клиентами HTTP/2. Сервер, который пытается завершить соединение, должен послать кадр GOAWAY с идентификатором последнего потока установленным равным 231-1 и кодом NO_ERROR. Эти сигналы клиенту о том, что shutdown близок и что не следует посылать новые запросы. После выдержки по крайней мере длительностью RTT сервер может послать еще один кадр GOAWAY с обновленным последним идентификатором потока. Это гарантирует, что соединение может быть прервано без потери запросов.

После посылки кадра GOAWAY, отправитель может выбрасывать кадры с идентификаторами выше, чем в последнем потоке. Однако, любые кадры, которые изменяют состояние соединения, игнорироваться не должны. Например, кадры HEADERS, PUSH_PROMISE и CONTINUATION должны по минимуму обрабатываться, чтобы гарантировать поддержку работы с компрессированными заголовками (смотри раздел 4.3); аналогично кадры DATA должны подсчитываться в рамках окна управления потоком. Ошибка при обработке этих кадров может вызвать разсинхронизацию управления потоком или состояния компрессии заголовков.

Кадр GOAWAY содержит также 32-битный код ошибки (раздел 7), который характеризует причину закрытия соединения.

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

6.9 WINDOW_UPDATE

Кадр WINDOW_UPDATE (тип=0x8) используется для управления потоком; смотри раздел 5.2.

Управление потоком работает на двух уровнях: на каждом из потокок и для всего соединения.

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

Управление потоком используется в отношении кадров, которые идентифицируются как объекты управления потоком. Это относится исключительно к кадрам DATA. Кадры, которые освобождены от управления потоком, должны восприниматься и обрабатываться, если только получатель не имеет доступа к ресурсам обработки кадра. Получатель может откликнуться сигналом ошибки потока (раздел 5.4.2) или ошибки соединения (раздел 5.4.1) типа FLOW_CONTROL_ERROR если он не может воспринять кадр.

Рис. 14. Формат поля данных WINDOW_UPDATE

Поле данных кадра WINDOW_UPDATE представляет собой один зарезервированный бит, плюс 31-битовое целое число без знака, указывающее число октетов, которое отправитель может передать в дополнение к существующему окну управления потоком. Допустимый диапазон для приращение размера окна управление потоком лежит между 1 и 231-1 (2.147.483.647) октетов.

Кадр WINDOW_UPDATE не определяет никаких флагов.

Кадр WINDOW_UPDATE может быть специфическим для потока или для всего соединения. В первом случае, идентификатор потока кадра указывает поток, к которому это имеет отношение, в последнем значение "0" индицирует, что все соединение является целью кадра.

Получатель должен рассматривать получение кадра WINDOW_UPDATE с приращением окна управления потоком 0 как ошибку потока (раздел 5.4.2) типа PROTOCOL_ERROR; ошибки, сопряженные с окном управления потоком соединения должны рассматриваться как ошибка соединения (раздел 5.4.1).

WINDOW_UPDATE может быть послано партнером, который послал кадр с флагом END_STREAM. Это означает, что получатель может получить кадр WINDOW_UPDATE для потока в "полузакрытом (удаленно)" или "закрытом" состоянии. Получатель не должен рассматривать это как ошибку, смотри раздел 5.1.

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

Кадр WINDOW_UPDATE с длиной отличной от 4 октетов должен рассматриваться как ошибка соединения (раздел 5.4.1) типа FRAME_SIZE_ERROR.

6.9.1 Окно управления потоком

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

Используется два окна управления потоком: окно управления и окно управление потоком соединения. Отправитель не должен посылать кадр управления потоком с длиной, которая превосходит размер доступного пространства в окнах управления потоком, анонсированных получателем. Кадры с нулевой длиной и с установленным флагом END_STREAM (то есть, пустой кадр DATA) могут быть посланы, если нет свободного места в обоих окнах управления потоком.

В расчете управления потоком, 9 октетов заголовка кадра не учитываются.

После отправки кадра управления потоком, отправитель уменьшает пространство доступное в обоих окнах на длину переданного кадра.

Получатель кадра посылает кадр WINDOW_UPDATE, так как это освобождает место в окнах управления потоком. Отдельные кадры WINDOW_UPDATE посылаются для окон управления потоком уровня потока и соединения.

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

Отправитель не должен разрешать ширину окна управления потоком превышающую 231-1 октетов. Если отправитель получает WINDOW_UPDATE, который вызывает расширение окна управления потоком больше допустимого максимума, он должен завершить либо поток либо соединение. Для потоков, отправитель посылает RST_STREAM с кодом ошибки FLOW_CONTROL_ERROR; для соединения, кадр GOAWAY с кодом FLOW_CONTROL_ERROR.

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

6.9.2 Начальный размер окна управления потоком

Когда соединение HTTP/2 установлено, создаются новые потоки с начальным размером окна управления потоком 65535 октетов. Окно управления потоком соединения равно 65535 октетов. Обе оконечные точки могут подстраивать размер исходного окна для новых потоков путем включения значения для SETTINGS_INITIAL_WINDOW_SIZE кадр SETTINGS, который образует часть преамбулы соединения. Окно управления потоком соединения может быть изменено с помощью кадров WINDOW_UPDATE.

Перед получением кадра SETTINGS, который устанавливает значение для SETTINGS_INITIAL_WINDOW_SIZE, оконечная точка при отправке кадров управления потоком может использовать только исходный размер окна по умолчанию. Аналогично, размер окна управления потоком соединения устанавливается равным значению по умолчанию до получения кадра WINDOW_UPDATE.

Кадр SETTINGS может изменить исходный размер окна управления потоком для всех потоков в состоянии "open" или "полузакрыт (удаленно)". Когда значение SETTINGS_INITIAL_WINDOW_SIZE изменяется, получатель должен изменить размер окон управления потоков, на величину разницы между новым и старым значениями.

Изменение SETTINGS_INITIAL_WINDOW_SIZE может привести к тому, что доступное пространство в окне управления потоком станет отрицательным. Отправитель должен отслеживать случаи негативных значений ширины окна управления потоком, и не должен посылать новых кадров управления потоком до тех пор пока не получит кадров WINDOW_UPDATE, которые сделают размер окна управления потоком положительным.

Например, если клиент посылает 60KB сразу после установления соединения, а сервер устанавливает начальный размер окна равным 16KB, клиент заново вычислит доступный размер окна управления потоком и получит -44KB по получении кадра SETTINGS. Клиент оставляет негативное значение ширины окна управления потоком до тех пор пока кадры WINDOW_UPDATE не сделают величину окна положительной, после этого клиент может возобновить отправку данных.

Кадр SETTINGS не может модифицировать окно управления потоком.

Оконечная точка должна рассматривать изменение SETTINGS_INITIAL_WINDOW_SIZE, которое вызывает превышение верхнего предела окна управления потоком, как ошибку соединения (раздел 5.4.1) типа FLOW_CONTROL_ERROR.

6.9.3 Уменьшение размера окна потока

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

После отправки кадра SETTINGS, который уменьшает начальный размер окна управления потоком, получатель может продолжить обработку потоков, которые превышают пределы управления потоком. Допущение продолжения потоков не позволяет получателю немедленно уменьшить пространство, зарезервированное для окон управления потоком. Рост этих потоков может затормозиться, так как нужно отправит кадры WINDOW_UPDATE, чтобы позволить отправителя возобновить отправку информации. Получатель может вместо этого послать RST_STREAM с кодом ошибки FLOW_CONTROL_ERROR для соответствующих потоков.

6.10 Кадр продолжения

Кадр продолжения (тип=0x9) используется, чтобы продолжить последовательность фрагментов блока заголовка (раздел 4.3). Может быть послано любое число кадров CONTINUATION, если последующий кадр принадлежит тому же потоку и кадр HEADERS, PUSH_PROMISE или CONTINUATION не имеет установленного флага END_HEADERS.

Фрагмент блока заголовка (*) ......

Рис. 15. Поле данных кадра продолжения

Поле данных кадра CONTINUATION содержит фрагмент блока заголовка (раздел 4.3).

Кадр CONTINUATION определяет следующий флаг:

END_HEADERS (0x4):
Бит 2 =1 индицирует, что этот кадр завершает блок заголовка (раздел 4.3).

Если бит END_HEADERS не установлен, за этим кадром должен следовать другой кадр CONTINUATION. Получатель должен рассматривать получение любого другого типа кадра или кадра из другого потока как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Кадр CONTINUATION изменяет состояние соединения, как это определено в разделе 4.3.

Кадры CONTINUATION должны быть привязаны к потоку. Если кадр CONTINUATION получен с полем идентификатора 0x0, получатель должен сигнализировать об ошибке соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

Перед кадром CONTINUATION должен прийти кадры HEADERS, PUSH_PROMISE или CONTINUATION без установленного флага END_HEADERS. Получатель, который детектирует нарушение этого правила должен сигнализировать об ошибке соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

7. Коды ошибок

Коды ошибок представляют собой 32-битные поля, которые используются в кадрах RST_STREAM и GOAWAY для передачи причины ошибки в потоке или соединении.

Коды ошибок используют общее пространство кодов. Некоторые коды ошибок относятся только к потокам или только к соединениям и не имеют определенной семантики в других контекстах.

Определены следующие коды ошибок:

NO_ERROR (0x0):
Соответствующие обстоятельства не являются результатом ошибки. Например, GOAWAY может включать этот код, чтобы индицировать стандартное завершение соединения.

PROTOCOL_ERROR (0x1):
Оконечная точка детектировала неспецифицированную протокольную ошибку. Эта ошибка предназначена для использования, когда более специфического кода нет.

INTERNAL_ERROR (0x2):
Оконечная точка столкнулась с неожиданной внутренней ошибкой.

FLOW_CONTROL_ERROR (0x3):
Оконечная точка детектировала, что ее партнер нарушил протокол управления потоком.

SETTINGS_TIMEOUT (0x4):
Оконечная точка посылает кадр SETTINGS, но не получает своевременно отклика. Смотри Settings Synchronization (раздел 6.5.3).

STREAM_CLOSED (0x5):
Оконечная точка получила кадр после перехода потока в состояние "полузакрыт".

FRAME_SIZE_ERROR (0x6):
Оконечная точка получила кадр неверного размера.

REFUSED_STREAM (0x7):
Оконечная точка отказывается от потока, прежде чем выполнять какие-либо приложения, подробности смотри в разделе 8.1.4.

CANCEL (0x8):
Используется оконечной точкой для индикации того, что поток более ненужен.

COMPRESSION_ERROR (0x9):
Оконечная точка не может поддерживать компрессию заголовка.

CONNECT_ERROR (0xa):
Соединение, установленное в ответ на запрос CONNECT (раздел 8.3) было сброшено или некорректно закрыто.

ENHANCE_YOUR_CALM (0xb):
Оконечная точка детектировала, что партнер демонстрирует поведение, которое может привести к генерированию чрезмерной нагрузки.

INADEQUATE_SECURITY (0xc):
Транспорт протокола имеет свойства, которые не соответствуют минимальным требованиям безопасности (смотри раздел 9.2).

HTTP_1_1_REQUIRED (0xd):
Оконечная точка требует, чтобы использовался HTTP/1.1 вместо HTTP/2.

Неизвестные или неподдерживаемые коды ошибок не должны вызывать какого-либо специфического поведения. Они могут интерпретироваться приложениями эквивалентно внутренним ошибкам (INTERNAL_ERROR).

8. Обмен сообщениями HTTP

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

Таким образом, спецификация и требования HTTP/1.1 семантики и содержимого [RFC7231], условные запросы [RFC7232], запросы фрагментов [RFC7233], кэширования [RFC7234] и авторизации [RFC7235] применимы и в HTTP/2.

8.1 Обмен запрос/отклик HTTP

Клиент посылает запрос HTTP в новый поток, используя неиспользованный ранее идентификатор потока (раздел 5.1.1). Сервер посылает HTTP-отклик в тот же поток, который использован для запроса.

Сообщение HTTP (запрос или отклик) состоит из:

  1. (только для отклика) нуля или более кадров HEADERS (за каждым следует нуль или более кадров CONTINUATION) содержащих заголовки сообщения информационного отклика (1xx) HTTP (смотри [RFC7230], раздел 3.2 и [RFC7231], раздел 6.2),
  2. один кадр HEADERS (за которым следует нуль или более кадров CONTINUATION), содержащих заголовки сообщения (смотри [RFC7230], раздел 3.2),
  3. нуль или более кадров DATA, содержащих тело сообщения (смотри [RFC7230], раздел 3.3), и
  4. опционно, один кадр HEADERS, за которым следует нуль или более кадров CONTINUATION, содержащих заключительную часть, если таковая имеется (смотри [RFC7230], раздел 4.1.2).

Последний кадр последовательности содержит флаг END_STREAM.

Другие кадры (из любого потока) не должны попадать ни между кадров HEADERS ни кадров CONTINUATION.

HTTP/2 использует кадры DATA для переноса полей данных сообщений.

Поля заключительной части заголовка содержатся в блоке заголовка, который завершает поток. Такой блок заголовка является последовательностью, начинающейся с кадра HEADERS, за которым следует нуль или более кадров CONTINUATION, где кадр HEADERS содержит флаг END_STREAM. Блоки заголовка после первого, который не завершает поток, не являются частью HTTP-запроса или отклика.

Кадр HEADERS (и сопряженные кадры CONTINUATION) могут появляться только в начале и конце потока. Оконечная точка, которая получает кадр HEADERS без флага END_STREAM после получения финального (неинформационного) статусного кода должна рассматривать соответствующий запрос или отклик, как сформированный некорректно (раздел 8.1.2.6).

Обмен HTTP запросами/откликами полностью занимает отдельный поток. Запрос начинается с кадра HEADERS, который переводит поток в состояние "open". Запрос завершается кадром, несущим END_STREAM, который переводит поток в состояние "полузакрыт (локально)" для клиента и "полузакрыт (удаленно)" для сервера. Отклик начинается с кадра HEADERS и завершается кадром, несущим флаг END_STREAM, который переводит поток в состояние "closed".

Отклик HTTP завершается после того как сервер посылает - или клиент получает - кадр с установленным флагом END_STREAM (включая любые кадры CONTINUATION, необходимые для завершения блока заголовка). Сервер может послать полный отклик до того, как клиент пришлет полный запрос, если отклик не зависит от какой-либо части запроса, который пока не послан. Когда это так, сервер может потребовать, чтобы клиент прервал передачу запроса без посылки кода ошибки RST_STREAM, а с кодом ошибки NO_ERROR после отправки всего отклика (т.e., кадра с флагом END_STREAM). Клиенты не должны отбрасывать отклики после получения RST_STREAM, хотя клиенты всегда могут отбрасывать отклики из каких-то своих соображений.

8.1.1 Переход от HTTP/2

HTTP/2 удаляет поддержку информационного статусного кода 101 (протокол коммутации) ([RFC7231], раздел 6.2.2).

Семантика 101 (протоколы коммутации) не применима к мультиплексным протоколам. Альтернативные протоколы могут использовать те же механизмы, которые использует HTTP/2 для согласования их применения (см. раздел 3).

8.1.2 Поля заголовка HTTP

Поля заголовка HTTP несет в себе информацию в виде серии пар ключ-значение. Список зарегистрированных HTTP-заголовков, смотри в разделе Message Header Field Registry в <https://www.iana.org/assignments/message-headers>.

Также как и в HTTP/1.x, имена полей заголовков являются строками ASCII-символов, которые сравниваются без учета регистра. Однако, имена полей заголовка должны быть представлены строчными символами прежде чем их перекодировать для HTTP/2. Запрос или отклик, содержащий в именах полей заглавные символы должны восприниматься как неверно сформированные (раздел 8.1.2.6).

8.1.2.1 Поля псевдозаголовка

При использовании начальной строки HTTP/1.x (смотри [RFC7230], раздел 3.1) для передачи адресного URI и метода запроса, а также статусного кода отклика, HTTP/2 использует специальные поля псевдозаголовков, начинающихся с символа ':' (ASCII 0x3a).

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

Поля псевдозаголовка применимы только в контексте, для которого они описаны. Поля псевдозаголовков, определенные для запросов не должны появляться в откликах; поля псевдозаголовков, определенные для откликов не должны появляться в запросах. Поля псевдозаголовко не должны появляться в секциях завершения (trailers). Оконечные точки должны рассматривать запросы или отклики, которые содержат неопределенные или некорректные поля псевдозаголовков как неверно сформированные (раздел 8.1.2.6).

Все поля псевдозаголовков должны появляться в блоке заголовка до регулярных полей заголовка. Любой запрос или отклик, который содержит поле псевдозаголовка, которое появляется после поля регулярного заголовка должно рассматриваться как ошибка (раздел 8.1.2.6).

8.1.2.2 Поля заголовка Connection-Specific

HTTP/2 не использует поле заголовка Connection для индикации полей заголовка специфичных для соединения. Оконечная точка не должна генерировать сообщения HTTP/2, содержащие поля специфичные для соединения; любое сообщение, содержащее такие поля, должно рассматриваться как некорректное (раздел 8.1.2.6).

Единственным исключение является поле заголовка TE, который может быть представлен в HTTP/2 запросе; когда он имеется, он не должен содержать никаких значений отличных от "trailers".

Это означает, что промежуточные узлы, преобразующие сообщения HTTP/1.x в HTTP/2 будут должны удалять любые поля заголовка номинированные полем заголовка Connection, вместе с самим полем Connection. Такие промежуточные узлы должны также удалить другие поля заголовка, специфические для соединения, такие как Keep-Alive, Proxy-Connection, Transfer-Encoding и Upgrade, даже если они не названы в Connection.

8.1.2.3 Поля псевдозаголовка запроса

Для HTTP/2 запросов определены следующие поля псевдозаголовков:

Это поле псевдозаголовка не должно быть пустым для URL http или https; http или https URI, которые не содержат компонента прохода, должны включать значение '/'. Исключением из этого правила является запрос OPTIONS для http или https URI, которое не содержит компонента path; они должны содержать поле псевдозаголовка :path со значением '*' (смотри [RFC7230], раздел 5.3.4).

Все запросы HTTP/2 должны содержать только одно значение для полей псевдозаголовка :method, :scheme, и :path, если только это не запрос CONNECT (раздел 8.3). Запрос HTTP, который опускает обязательные поля псевдозаголовка, считается некорректным (раздел 8.1.2.6).

8.1.2.4 Поля псевдозаголовка отклика

Для откликов HTTP/2 определено поле псевдозаголовка :status, в котором содержится статусное слово HTTP (смотри [RFC7231], раздел 6). Это поле псевдозаголовка должно быть включено во все отклики, в противном случае отклик считается некорректным (раздел 8.1.2.6).

8.1.2.5 Компрессия поля заголовка Cookie

Поле заголовка Cookie [COOKIE] использует (";") для разделения cookie-пар. Это поле заголовка не следует ограничительным правилам HTTP (смотри [RFC7230], раздел 3.2.2), что предотвращает превращение cookie-пар в пары имя-значение.

Чтобы повысить эффективность компрессии, поле заголовка Cookie может быть разделено на отдельные поля заголовка, в каждом из которых помещается одна или более cookie-пар. Если после декомпрессии получено несколько полей заголовка Cookien, они должны быть объединены в одну строку октетов с помощью двухоктетных разграничителей 0x3B, 0x20 (ASCII строка "; ") до передачи ее в контекст не-HTTP, такой как HTTP/1.1 соединение, или общее HTTP-приложение сервера.

Следовательно, последующие два списка полей заголовков Cookie семантически эквивалентны.

  cookie: a=b; c=d; e=f
  cookie: a=b
  cookie: c=d
  cookie: e=f

8.1.2.6 Некорректно сформированные запросы и отклики

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

Запрос или отклик, который содержит поле данных, может содержать поле заголовка content-length (длина содержимого). Запрос или отклик является некорректным, если значение поля заголовка content-length не равно суммарной длине фрагментов поля данных. Отклик, который не имеет поля данных, как это описано в [RFC7230], раздел 3.3.2, может иметь ненулевое поле заголовка content-length, даже при отсутствии содержимого в кадрах DATA.

Промежуточные узлы, которые обрабатывают HTTP-запросы или отклики (т.e., любые посредники, которые работают не как туннели) не должны переадресовывать некорректные запросы или отклики. Детектированные некорректные запросы или отклики должны рассматриваться как ошибки потока (раздел 5.4.2) типа PROTOCOL_ERROR.

Для некорректных запросов сервер может послать HTTP-отклик, прежде чем закроет поток. Клиенты не должны воспринимать некорректные отклики. Заметим, что требования имеют целью защититься от нескольких типов атак HTTP.

8.1.3 Примеры

В этом разделе представлены HTTP/1.1 запросы и отклики, и их эквиваленты в HTTP/2.

Запрос HTTP GET включает в себя поля заголовков и никакого поля данных. В этом случае передается один кадр HEADERS, за которым следует нуль или более кадров CONTINUATION, содержащих последовательность полей заголовка. Кадр HEADERS в ниже приведенных примерах содержит установленные флаги END_HEADERS и END_STREAM; не посылается никаких кадров CONTINUATION:

GET /resource HTTP/1.1           HEADERS
  Host: example.org          ==>     + END_STREAM
  Accept: image/jpeg                 + END_HEADERS
                                       :method = GET
                                       :scheme = https
                                       :path = /resource
                                       host = example.org
                                       accept = image/jpeg

Аналогично, отклик, который содержит только поля заголовка, передается как кадр HEADERS (здесь снова нет кадров CONTINUATION), содержащий последовательность полей заголовка.

  HTTP/1.1 304 Not Modified        HEADERS
  ETag: "xyzzy"              ==>     + END_STREAM
  Expires: Thu, 23 Jan ...           + END_HEADERS
                                       :status = 304
                                       etag = "xyzzy"
                                       expires = Thu, 23 Jan ...

Запрос HTTP POST, который включает поля заголовка и поле данных, передается в виде одного кадра HEADERS, за которым следует нуль или более кадров CONTINUATION, содержащих поля заголовка запроса, за которым следует один или более кадров DATA, с последним кадром CONTINUATION (или HEADERS), имеющим установленный флаг END_HEADERS. В последнем кадре DATA будет установлен флаг END_STREAM:

  POST /resource HTTP/1.1          HEADERS
  Host: example.org          ==>     - END_STREAM
  Content-Type: image/jpeg           - END_HEADERS
  Content-Length: 123                  :method = POST
                                       :path = /resource
  {двоичные данные}                    :scheme = https
 
                                   CONTINUATION
                                     + END_HEADERS
                                       content-type = image/jpeg
                                       host = example.org
                                       content-length = 123
 
                                   DATA
                                     + END_STREAM
                                   {двоичные данные}

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

Отклик, который содержит поля заголовка и поле данных пересылается в виде кадра, за которым следует нуль или более кадров CONTINUATION, после которым может быть один или более кадров DATA, с последним кадром, содержащим установленный флаг END_STREAM:

  HTTP/1.1 200 OK                  HEADERS
  Content-Type: image/jpeg   ==>     - END_STREAM
  Content-Length: 123                + END_HEADERS
                                       :status = 200
  {двоичные данные}                 content-type = image/jpeg
                                       content-length = 123
 
                                   DATA
                                     + END_STREAM
                                   {двоичные данные}

Информационный отклик, использующий статусный код 1xx отличный от 101 передается в кадре HEADERS, за которым следует нуль или более кадров CONTINUATION.

Завершающие поля заголовка пересылаются в виде блока заголовка после блоков запроса или отклика и всех кадров DATA. Кадр HEADERS, начинающийся с завершающего блока заголовка имеет установленный флаг END_STREAM.

Следующий пример содержит как статусный код 100 (Continue), который посылается в отклике на запрос, содержащий лексему "100-continue" в поле заголовка Expect, так и завершающие поля заголовка (trailing header fields):

  HTTP/1.1 100 Continue            HEADERS
  Extension-Field: bar       ==>     - END_STREAM
                                     + END_HEADERS
                                       :status = 100
                                       extension-field = bar
 
  HTTP/1.1 200 OK                  HEADERS
  Content-Type: image/jpeg   ==>     - END_STREAM
  Transfer-Encoding: chunked         + END_HEADERS
  Trailer: Foo                         :status = 200
                                       content-length = 123
  123                                  content-type = image/jpeg
  {двоичные данные}                 trailer = Foo
  0
  Foo: bar                         DATA
                                     - END_STREAM
                                   {двоичные данные}
 
                                   HEADERS
                                     + END_STREAM
                                     + END_HEADERS
                                       foo = bar

8.1.4 Механизмы надежности запросов в HTTP/2

В HTTP/1.1, клиент HTTP не может повторно послать не идемпотентный запрос в случае возникновения ошибки, так как не существует средств определить природу ошибки. Возможно, что какая-то обработка сервера случилась до ошибки, которая может вызвать нежелательные эффекты, если будет предпринята попытка повторить запрос.

HTTP/2 предоставляет два механизма для гарантии клиенту, что запрос не был обработан:

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

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

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

8.2 Push сервера

HTTP/2 позволяет серверу послать опережающие (или "push") отклики (вместе с соответствующим будущими ("promised") запросами) клиенту в связи с предыдущим запросом клиента. Это может быть полезно, когда сервер знает, что клиенту будут нужны эти отклики.

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

Обещанные (Promised) запросы должны быть кэшируемыми (смотри [RFC7231], раздел 4.2.3), безопасными (смотри [RFC7231], раздел 4.2.1) и не должны содержать тело запроса. Клиенты, которые получают обещанный запрос, который не является кэшируемым, не знают, является ли он безопасным или что означает присутствие тела запроса, должны сбросить обещанный поток с указанием ошибки потока (раздел 5.4.2) типа PROTOCOL_ERROR. Это может случиться, если клиент не распознает вновь определенный метод, как безопасный.

Pushed отклики, которые кэшируемы (смотри [RFC7234], раздел 3) могут быть запомнены клиентом, если он использует HTTP кэш. Pushed отклики рассматриваются успешно проверенными на исходном сервере (напр., если в отклике присутствует директива "no-cache" [RFC7234], раздел 5.2.2), когда поток, идентифицированный обещанным ID потока, является открытым.

Pushed отклики, которые некэшируемы, не должны запоминаться любым HTTP кэшем.

Сервер должен включать значение поля заголовка :authority для которого сервер авторизован (смотри Раздел 10.1). Клиент должен MUST рассматривать PUSH_PROMISE для которого сервер не авторизован, как ошибку потока (раздел 5.4.2) типа PROTOCOL_ERROR.

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

Клиент не может осуществлять push. Таким образом, серверы должны рассматривать получение кадра PUSH_PROMISE как ошибку соединения (раздел 5.4.1) типа PROTOCOL_ERROR. Клиенты должны отвергать любые попытки изменить установку SETTINGS_ENABLE_PUSH равной любому значению кроме нуля. В противном случае генерируется сигнал ошибки соединения (раздел 5.4.1) типа PROTOCOL_ERROR.

8.2.1 Запросы Push

Сервер push семантически эквивалентен посылке сервером отклика на запрос; однако, в этом случае такой запрос посылается также сервером в кадре PUSH_PROMISE.

Кадр PUSH_PROMISE содержит блок заголовка, который несет в себе полный набор полей заголовка запроса сервера. Нельзя реализовать push-отклик на запрос, который содержит тело запроса.

Pushed отклики всегда ассоциированы с явным запросом клиента. Кадры PUSH_PROMISE, посланные сервером, включены в явный поток запросов. Кадр PUSH_PROMISE включает в себя обещанный (promised) идентификатор потока, выбранный из числа идентификаторов потока доступных серверу (смотри раздел 5.1.1).

Поля заголовка в PUSH_PROMISE и любые последующие кадры CONTINUATION должны быть корректны и составлять полный набор ролей заголовка запроса (Раздел 8.1.2.3). Сервер должен включить метод в поле заголовка :method, который является безопасным и кэшируемым. Если клиент получает PUSH_PROMISE, который не содержит полного и корректного набора полей заголовка, или поля заголовка :method, значение которого безопасно, он должен реагировать сигналом ошибки потока (раздел 5.4.2) типа PROTOCOL_ERROR.

Сервер должен посылать кадры PUSH_PROMISE (Раздел 6.6) до посылки любых кадров, которые ссылаются на обещанные отклики. Это исключает гонку, где клиенты выдают запросы до получения каких-либо кадров PUSH_PROMISE.

Например, если сервер получает запрос документа, содержащего встроенные связи с несколькими файлами картинок, и сервер решает выдать (push) эти дополнительные изображения клиенту, посылая "push promises" до кадров DATA, которые содержат связи с файлами изображений, гарантирует, что клиент будет способен увидеть эти картинки до того, как обнаружит вложенные ссылки. Аналогично, если сервер выдает "pushes responses", на который ссылается блок заголовка (например, в полях заголовка Link), посылая "push promises" до отправки блока заголовка, это гарантирует, что клиент не будет их запрашивать.

Кадры PUSH_PROMISE не должны посылаться клиентом.

Кадры PUSH_PROMISE могут быть посланы сервером в ответ через любой инициированный клиентом поток, но поток должен быть в состоянии либо "open" либо "полузакрыт (удаленно)" в отношении сервера. Кадры PUSH_PROMISE смешаны с кадрами, которые образуют отклик, хотя они не могут быть перемешаны с кадрами HEADERS и CONTINUATION, которые образуют единый блок заголовка.

Посылка кадра PUSH_PROMISE создает новый поток и переводит его в состояние “зарезервировано (локально)” для сервера и “зарезервировано (удаленно)” для клиента.

8.2.2 Отклики Push

После посылки кадра PUSH_PROMISE, сервер может начать доставку откликов pushed как отклик (раздел 8.1.2.4) на инициированный сервером поток, который использует обещанный идентификатор потока. Сервер использует этот поток для передачи HTTP-отклика, используя ту же последовательность кадров, которая определена в разделе 8.1. Этот поток оказывается в состоянии "полузакрыт" для клиента (раздел 5.1) после посылки исходного кадра HEADERS.

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

Если клиент определяет, по какой-либо причине, что он не хочет получать отклик от сервера, или если сервер слишком долго не отправляет обещанный отклик, клиент может послать кадр RST_STREAM, используя либо код CANCEL, либо REFUSED_STREAM, и используя идентификатор потока pushed.

Клиент может использовать установку SETTINGS_MAX_CONCURRENT_STREAMS, чтобы ограничить число откликов, которые могут быть одновременно выданы сервером. Анонсированная величина SETTINGS_MAX_CONCURRENT_STREAMS нуль блокирует операцию push сервера, препятствуя созданию необходимых потоков. Это не препятствует серверу направить кадры PUSH_PROMISE; клиентам нужно сбросить обещанные потоки, которые им не нужны.

Клиенты, полчая pushed отклики, должны проверить, что либо авторизован сервер (смотри раздел 10.1), либо прокси, который передал этот отклик, сконфигурирован для соответствующего запроса. Например, сервер, который предлагает сертификат для DNS-ID example.com или не разрешено имя Common для push-отклика для https://www.example.org/doc.

Отклик для потока PUSH_PROMISE начинается с кадра HEADERS, который немедленно переводит поток в состояние “полузакрыто (удаленно)” для сервера и “полузакрыт (локально)” для клиента, и завершает с помощью кадра END_STREAM, который переводит поток в состояние "closed".

Замечание:

Клиент никогда не посылает кадра с флагом END_STREAM для push сервера.

8.3 Метод CONNECT

В HTTP/1.x, псевдометод CONNECT ([RFC7231], раздел 4.3.6) используется для преобразования HTTP-соединения в туннель до удаленного компьютера. CONNECT первоначально использовался HTTP-прокси для установления TLS-сессии с исходным сервером для целей взаимодействия с https-ресурсами.

В HTTP/2, метод CONNECT используется для установления туннеля через отдельный HTTP/2 поток к удаленному компьютеру, для аналогичных целей. Мэпинг поля заголовка HTTP работает так, как это определено в полях заголовка запроса (раздел 8.1.2.3), с небольшими отличиями В частности:

Запрос CONNECT, который не отвечает этим ограничениям, сформирован некорректно (раздел 8.1.2.6).

Прокси, который поддерживает CONNECT устанавливает TCP-соединение [TCP] с сервером, идентифицированным в поле заголовка :authority. Когда соединение установлено, прокси посылает клиенту кадр HEADERS, содержащий статусный код серии 2xx, как это определено в [RFC7231], раздел 4.3.6.

После посылки исходного кадра HEADERS каждым из партнеров, все последующие кадры DATA соответствуют данным, посланным через TCP-соединение. Поле данных любого кадра DATA, посылаемого клиентом передается прокси TCP-серверу; данные, полученные от TCP-сервера формируются прокси в кадры DATA. Кадры с типами отличными от DATA или кадров управления потоком (RST_STREAM, WINDOW_UPDATE и PRIORITY) не должны пересылаться через поток, и должны рассматриваться при получении, как ошибка потока (раздел 5.4.2).

TCP-соединение может быть закрыто любым из партнеров. Флаг END_STREAM кадра DATA рассматривается эквивалентным биту FIN TCP. Ожидается, что клиент пошлет кадр DATA с установленным флагом END_STREAM после получения кадра, несущего флаг END_STREAM. Прокси, который получает кадр DATA с установленным флагом END_STREAM, посылает присоединенные данные с установленным битом FIN в последнем сегменте TCP. Прокси, который получает TCP-сегмент с установленным битом FIN, посылает кадр DATA с установленным флагом END_STREAM. Заметим, что последний TCP-сегмент или кадр DATA могут быть пустыми.

Ошибка TCP-соединения пересылается посредством RST_STREAM. Прокси рассматривает любую ошибку ТCP-соединения, которая охватывает получение TCP-сегмента с установленным битом RST, как ошибку потока (раздел 5.4.2) типа CONNECT_ERROR. Соответственно, прокси должен послать TCP-сегмент с установленным битом RST, если он детектирует ошибку потока или HTTP/2 соединения.

9. Дополнительные HTTP требования/соображения

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

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

HTTP/2 соединения являются устойчивыми. Для улучшения рабочих характеристик ожидается, что клиенты не будут закрывать соединение до тех пор, пока не будет выяснено, что коммуникации с сервером более не нужны (например, когда пользователь покидает конкретную WEB-страницу) или пока сервер не закроет соединение.

Клиенты не должны открывать более одного HTTP/2 соединения с конкретным компьютером и портом, где имя компьютера извлекается из URI, [ALT-SVC] или конфигурации прокси.

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

Клиент может открыть несколько соединений с одним и тем же IP-адресом и TCP-портом, используя разные имена сервера [TLS-EXT] или обеспечить разные TLS-сертификаты клиента, но следует избегать создания нескольких соединений с идентичными конфигурациями.

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

9.1.1 Повторное использование соединения

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

Для ресурсов https, повторное использование соединения кроме того зависит от наличия сертификата, который пригоден для компьютера данного URI. Сертификат, предложенный сервером, должен удовлетворять всем критериям проверки, которые клиент может реализовать в процессе формирования нового TLS-соединения для компьютера данного URI.

Исходный сервер может предложить сертификат с несколькими атрибутами subjectAltName, или имена с произвольной подменой (wildcard). Например, сертификат с subjectAltName *.example.com может позволять использование одного и того же соединения для запросов к URIs, начинающихся с https://a.example.com/ и https://b.example.com/.

В некоторых приложениях, повторное использование соединения для нескольких точек может привести к посылке запросов по неверному адресу. Например, TLS отключение может быть выполнено промежуточным узлом, который использует расширение SNI (Server Name Indication) TLS-сервера [TLS-EXT] для выбора исходного сервера. Это означает, что появляется возможность для клиентов послать конфиденциальную информацию совсем не тому серверу, которому хотелось.

Сервер, который не хочет чтобы клиенты повторно использовали соединение, может указать , что он не имеет полномочий для в ответ на запрос пересылки отклика со статусным кодом 421 (Misdirected Request) (смотри раздел 9.1.2).

Клиент, который сконфигурирован для использования прокси поверх HTTP/2, направляет запросы прокси через одно соединение.

9.1.2 Статусный код 421 (Misdirected Request)

Статусный код 421 (Misdirected Request) указывает, что запрос был направлен серверу, который не способен сформировать отклик. Этот код может быть послан сервером, который не сконфигурирован выдавать отклики для данной комбинации схемы и полномочий (authority), которые присутствуют в URI запроса.

Клиенты, получающие отклик 421 (Misdirected Request) от сервера могут попытаться повторить запрос через другое соединение. Это возможно, если соединение используется повторно (раздел 9.1.1) или если выбран альтернативный сервис ([ALT-SVC]).

Этот статусный код не должен генерироваться прокси.

Отклик 421 является кэшируемым по умолчанию; т.e., если не указано обратного в описании метода или явно не прописан запрет кэширования (смотри раздел 4.2.2 [RFC7234]).

9.2 Использование параметров TLS

Реализации HTTP/2 должны использовать TLS [TLS12] версии 1.2 или выше для HTTP/2 поверх TLS.

Реализации TLS должны поддерживать расширения SNI (Derver Name Indication) [TLS-EXT] для TLS. Клиенты HTTP/2 должны при согласовании применения TLS указывать имя домена адресата.

Приложение HTTP/2, которое согласует TLS 1.3 или выше требует поддержки расширений SNI.

9.2.1 Характеристики TLS 1.2

Этот раздел описывает ограничения на набор характеристик TLS 1.2, который может использоваться с HTTP/2. Из-за ограничений применения может оказаться невозможным не согласовать TLS, когда эти ограничения полностью удовлетворены. Оконечная точка может немедленно прервать соединение HTTP/2, которое не удовлетворяет требованиям TLS с ошибкой соединения (Раздел 5.4.1) типа INADEQUATE_SECURITY.

Применение HTTP/2 поверх TLS 1.2 должно запретить компрессию. Компрессия TLS может привести к раскрытию информации, которая в противном случае была бы невозможной [RFC3749]. Обычная компрессия не нужна, так как HTTP/2 предоставляет средства компрессии, которые лучше по характеристикам, по безопасности и другим причинам.

Применение HTTP/2 поверх TLS 1.2 должно запретить повторное согласование. Оконечная точка должна рассматривать повторное согласование TLS как ошибку соединения (раздел 5.4.1)типа PROTOCOL_ERROR. Заметим, что запрет согласования может привести к тому, что долго живущие соединения окажутся непригодными для применения по криптографическим причинам.

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

Это эффективно предотвращает использование повторного согласования в отклике на запрос особо защищенного ресурса. В качестве альтернативы сервер может использовать ошибку (раздел 5.4) типа HTTP_1_1_REQUIRED, когда клиент пытается использовать протокол, который допускает повторное согласование.

Реализации должны поддерживать обмен криптоключами по крайней мере длиной 2048 бит для криптонаборов, которые используют алгоритмы Diffie-Hellman (DHE) [TLS12] и 224 битовых для алгоритмов на основе элиптических кривых (ECDHE) [RFC4492]. Клиенты должны воспринимать DHE размеры вплоть до 4096 бит. Оконечные точки могут рассматривать попытки использования более коротких ключей как ошибку соединения (раздел 5.4.1) типа INADEQUATE_SECURITY.

9.2.2 Наборы шифров TLS 1.2

Применение HTTP/2 поверх TLS 1.2 не должно использовать любой шифровой набор из черного списка (Приложение A).

Оконечные точки могут решить генерировать ошибку соединения (раздел 5.4.1) типа INADEQUATE_SECURITY, если согласуется один из шифровых наборов из черного списка. Реализация, которая решает использовать шифровой набор из черного списка, рискует активировать ошибку соединения, если только потенциальные партнеры готовы воспринять этот набор.

Реализации не должны генерировать эту ошибку в ответ на согласование шифрового набора, который не входит в черный список. Следовательно, когда клиенты предлагают шифровой набор, которого нет в списке, они должны быть готовы использовать этот набор совместно с HTTP/2.

Черный список включает в себя шифровой набор, который TLS 1.2 считает обязательным, что означает, что реализации TLS 1.2 могут иметь непересекающиеся наборы разрешенных шифровых наборов. Чтобы избежать этой проблемы, вызывающей сбои согласования шифровых наборов TLS, реализации HTTP/2, которые используют TLS 1.2 должны поддерживать TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [TLS-ECDHE] с элиптическими кривыми P256 [FIPS186].

Заметим, что клиенты могут анонсировать поддержку шифровых наборов из черного списка, для того чтобы позволить для соединений с серверами, которые не поддерживают HTTP/2. Это позволит серверам выбрать HTTP/1.1 с шифровым набором, который находится в черном списке HTTP/2. Однако, это может привести к тому что в HTTP/2 будет согласовываться шифровой набор из черного списка, если протокол приложения и крипто шифр выбраны независимо.

10. Соображения безопасности

10.1 Authority сервера

HTTP/2 полагается на HTTP/1.1 определение authority для определения, имеет ли сервер полномочия для выдачи данного отклика, смотри [RFC7230], раздел 9.1. Это базируется на локальном анализе для схемы "http" URI, и распознавании сервера в рамках схемы "https" (смотри [RFC2818], раздел 3).

10.2 Кроспротокольные атаки

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

Исчерпывающий TLS-диалог с ALPN-идентификатором для HTTP/2 может считаться достаточной защитой от кроспротокольных атак. ALPN обеспечивает подтверждение того, что сервер намерен работать с HTTP/2, который предотвращает атаки через другие протоколы, базирующиеся на TLS.

Шифрование в TLS усложняет для атакеров контроль данных, которые могут быть использованы для кроспротокольных атак протоколов с открытыми текстами.

Версия HTTP/2 с открытыми текстами имеет минимальную защиту от кроспротокольных атак. Преамбула соединения (раздел 3.5) содержит строку, которая может спутать HTTP/1.1 серверы, но никакой специальной защиты не предусмотрено для других протоколов. Сервер, который хочет игнорировать части запроса HTTP/1.1, содержащие поле заголовка Upgrade в дополнение к преамбуле соединения клиента, может быть уязвим для кроспротокольной атаки.

10.3 Атаки промежуточной инкапсуляции

Кодировка поля заголовка HTTP/2 допускает выражения имен, которые не являются корректными именами полей в синтаксисе Интернет сообщений, используемом HTTP/1.1. Запросы или отклики, содержащие некорректные имена полей заголовка должны рассматриваться как неверные (Раздел 8.1.2.6). Промежуточные узлы, следовательно, не могут транслировать запрос или отклик HTTP/2, содержащие неверные имена полей заголовка в сообщение HTTP/1.1.

Аналогично, HTTP/2 допускает значения поля заголовка, которое некорректно. В то время как большинство значений, которые могут кодироваться, не изменяют анализа поля заголовка, атакер может использовать символы возврата каретки (CR, ASCII 0xd), перевода строки (LF, ASCII 0xa) и нуля (NUL, ASCII 0x0), если они транслируются буквально. Любой запрос или отклик, который содержит символ, неразрешенный в поле заголовка, должен рассматриваться как некорректный (раздел 8.1.2.6). Корректные символы определены в правиле о содержимом полей ABNF в разделе 3.2 [RFC7230].

10.4 Кэшируемость Pushed откликов

Отклики Pushed не соответствуют явно запросу клиента; запрос посылается сервером в кадре PUSH_PROMISE.

Кэширование откликов, которые являются "pushed" возможно на основе управления, осуществляемого исходным сервером посредством поля заголовка Cache-Control. Однако, это может вызвать проблемы, если один сервер предоставляет услуги боле чем одному клиенту. Например, сервер может предложить нескольким пользователям небольшие части своего пространства URI.

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

Выставленные отклики, для которых исходный сервер не имеет полномочий, (смотри раздел 10.1) не должны использоваться или кэшироваться.

10.5 Соображения по поводу отказа обслуживания

Соединение HTTP/2 может требовать больших ресурсов для работы, чем соединение HTTP/1.1. Использование компрессии заголовков и управление потоком зависят от ресурсов, необходимых для запоминания и долговременного хранения. Установки для этих функций гарантируют, что объем памяти для их реализации строго ограничен.

Число кадров PUSH_PROMISE не имеет аналогичного ограничения. Клиент, который принимает push от сервера, должен ограничить число потоков, которое он позволяет реализовать в состоянии "зарезервировано (удаленно)". Избыточное число push-потоков сервера будет рассматриваться как ошибка потока (раздел 5.4.2) типа ENHANCE_YOUR_CALM.

Кадр SETTINGS может использоваться некорректно, чтобы заставить партнера тратить дополнительное время. Это может быть сделано путем неэффективного изменения параметров SETTINGS, устанавливая много неопределенных параметров, или изменяя один и тот же много раз в одном и том же кадре. Кадры WINDOW_UPDATE или PRIORITY могут использоваться с целью расходования ресурсов.

Большое число небольших или пустых кадров может использоваться, чтобы вынудить партнера увеличить время обработки заголовков кадров. Заметим однако, что эти действия могут быть вполне легальными, такие как посылка пустых кадров DATA или CONTINUATION в конце потока.

Компрессия заголовка предоставляет также некоторые возможности впустую тратить ресурсы; смотри раздел 7 [COMPRESSION].

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

Все эти особенности - т.e., изменения SETTINGS, малые кадры, компрессия заголовка - вполне допустимы. Эти свойства становятся обузой только когда используются без необходимости или чрезмерно.

Оконечная точка, которая не мониторирует это поведение, подвергает себя риску атаки отказа обслуживания. Реализации должны отслеживать использование таких возможностей и установить пределы их использования. Оконечная точка может рассматривать активность, которая представляется подозрительной, как ошибку соединения (раздел 5.4.1) типа ENHANCE_YOUR_CALM.

10.5.1 Предельные размеры блока заголовка

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

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

Сервер, который получает больший блок заголовка, чем он намерен использовать, может послать статусный код HTTP 431 (Request Header Fields Too Large) [RFC6585]. Клиент может отбросить отклик, который он не может обработать. Блок заголовка должен быть обработан, чтобы гарантировать согласованность состояния соединения, если только соединение не закрыто.

10.5.2 Проблемы CONNECT

Метод CONNECT может использоваться для создания непомерной нагрузки прокси, так как создание потока является относительно недорогим по сравнению с созданием и поддержанием TCP-соединения. Прокси может также поддерживать некоторые ресурсы для TCP-соединения за пределами закрытия потока, который несет запрос CONNECT, так как исходящее TCP-соединение остается в состоянии TIME_WAIT. Прокси следовательно не может полагаться только на SETTINGS_MAX_CONCURRENT_STREAMS для ограничения расходования ресурсов запросами CONNECT.

10.6 Использование компрессии

Компрессия может позволить атакеру восстановить секретные данные, когда они компрессированы в том же контексте, что и данные под контролем атакера. HTTP/2 допускает компрессию полей заголовка (раздел 4.3).

Существуют демонстрируемые атаки через компрессию, которые используют характеристики web (напр., [BREACH]). Атакер вводит несколько запросов, содержащих варьируемый открытый текст, отслеживает длину зашифрованного текста для каждого варианта, при этом считается, что более короткий текст получается, когда ключ угадан.

Реализации, работающие через секретный канал не должны компрессировать содержимое, которое включает в себя как конфиденциальную и контролируемую атакером информацию, если только не используются разные словари сжатия для этих двух видов данных. Компрессия не должна использоваться, если источник данных не может быть надежно идентифицирован. Общая компрессия потока, такая, которая реализуется TLS не должна использоваться с HTTP/2 (смотри раздел 9.2).

10.7 Использование заполнителей

Заполнители в HTTP/2 служат не только для традиционных целей, как это работает в TLS [TLS12]. Избыточное применение заполнителей может быть контрпродуктивным. Корректное применение может зависеть от наличия специальных знаний данных, с которыми использованы заполнители.

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

Заполнители могут использоваться скрыть точный объем данных в кадре, и обеспечить уменьшение вероятности атак протокола HTTP. Например, атак, где архивированные данные содержат открытый текст, контролируемый атакером, и секретную информацию (смотри, например, [BREACH]).

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

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

10.8 Соображения конфиденциальности

Несколько характеристик HTTP/2 предоставляет эксперту возможность соотносить действия отдельного клиента или сервера со временем. Это включает значения установки, манеры регулирования окна управления потоком, способа присвоения приоритетов потокам, таймирование откликов на стимулы и оперирование любыми характеристиками, которые управляются установками.

Поскольку это создает наблюдаемое отличие в поведении, они могут использоваться как основа для распознавания специфических клиентов, как это описано в разделе 1.8 [HTML5].

Предпочтение HTTP/2 использования одного TCP-соединения позволяет отслеживать активность пользователей на сайте. Если соединения используются повторно для разных исходных точек, это позволяет отслеживать эти точки.

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

11. Соображения IANA

Строка для идентификации HTTP/2 передается в регистр ALPN (Application Layer Protocol Negotiation Protocol IDs), организованный в [TLS-ALPN].

Данный документ устанавливает регистр для типов кадров, установок и кодов ошибок. Эти новые записи включены в новый раздел "Hypertext Transfer Protocol (HTTP) 2 Parameters".

Этот документ вводит поле заголовка HTTP2-Settings для использования в; и статусный код 421 (Misdirected Request).

В этом документе введен новый метод PRI для работы с HTTP, чтобы избежать коллизий с преамбулой соединения (раздел 3.5).

11.1 Регистрация идентификационных строк HTTP/2

Этот документ создает две регистрации для идентификации HTTP/2 в регистре "Application Layer Protocol Negotiation (ALPN) Protocol IDs", установленном в [TLS-ALPN].

Строка "h2" идентифицирует HTTP/2 при использовании поверх TLS:

Протокол:
HTTP/2 поверх TLS

Идентификационная последовательность:
0x68 0x32 ("h2")

Спецификация:
Данный документ

Строка "h2c" идентифицирует HTTP/2, когда используется поверх TCP и открытый текст:

Протокол:
HTTP/2 поверх TCP

Идентификационная последовательность:
0x68 0x32 0x63 ("h2c")

Спецификация:
Данный документ

11.2 Регистр типов кадров

Данный документ устанавливает регистр для кодов типа кадров HTTP/2. Регистр "HTTP/2 Frame Type" регулирует 8-битовое пространство. Регистр "HTTP/2 Frame Type" работает в рамках of the "IETF Review" или "IESG Approval" [RFC5226] для значений между 0x00 и 0xef, и значениями между 0xf0 и 0xff зарезервированными для экспериментальных целей.

Новая запись в этот регистр требует следующей информации:

Тип кадра:
Имя или метка для типа кадра.

Код:
8-битовый код, приписанный типу кадра.

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

Записи в ниже приведенной таблице зарегистрированы данным документом.

Тип кадраКодРаздел
DATA0x0Раздел 6.1
HEADERS0x1Раздел 6.2
PRIORITY0x2Раздел 6.3
RST_STREAM0x3Раздел 6.4
SETTINGS0x4Раздел 6.5
PUSH_PROMISE0x5Раздел 6.6
PING0x6Раздел 6.7
GOAWAY0x7Раздел 6.8
WINDOW_UPDATE0x8Раздел 6.9
CONTINUATION0x9Раздел 6.10

11.3 Регистр установок (Settings)

Данный документ устанавливает регистр установок HTTP/2. Регистр "HTTP/2 Settings" управляет 16-битовым пространством. Регистр "HTTP/2 Settings" работает в рамках "Expert Review" [RFC5226] для величин в диапазоне от 0x0000 до 0xefff, со значениями между 0xf000 и 0xffff, зарезервированными для экспериментальных нужд.

При новой регистрации рекомендуется предоставлять следующие данные:

Имя:
Символическое имя для установки. Спецификация имени является опционной.

Код:
16-битовый код, приписываемый установке.

Исходное значение:
Исходное значение установки.

Спецификация:
Опционная ссылка на спецификацию, которая описывает использование установок.

Перечень исходных наборов установок можно найти в разделе 6.5.2.

ИмяКодНачальное значениеСпецификация
HEADER_TABLE_SIZE0x14096Раздел 6.5.2
ENABLE_PUSH0x21Раздел 6.5.2
MAX_CONCURRENT_STREAMS0x3(infinite)Раздел 6.5.2
INITIAL_WINDOW_SIZE0x465535Раздел 6.5.2
MAX_FRAME_SIZE0x516384Раздел 6.5.2
MAX_HEADER_LIST_SIZE0x6(infinite)Раздел 6.5.2

11.4 Регистр кодов ошибок

Данный документ устанавливает регистр для кодов ошибки HTTP/2. Регистр "HTTP/2 Error Code" управляет 32-битовым пространством. Регистр "HTTP/2 Error Code" работает в рамках политики "Expert Review" [RFC5226].

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

При новой регистрации рекомендуется приводить следующие данные:

Имя:
Имя кода ошибки. Спецификация кода ошибки является опционной.

Код:
32-битовое значение кода ошибки.

Описание:
Краткое описание семантики кода ошибки, длиннее, если не предлагается подробной спецификации.

Спецификация:
Опционная ссылка для спецификации, которая определяет код ошибки.

Записи в последующей таблице зарегистрированы в данном документе.

ИмяКодОписаниеСпецификация
NO_ERROR0x0Нормальное завершениеРаздел 7
PROTOCOL_ERROR0x1Детектирована протокольная ошибкаРаздел 7
INTERNAL_ERROR0x2Ошибка реализацииРаздел 7
FLOW_CONTROL_ERROR0x3Превышен предел управления потокомРаздел 7
SETTINGS_TIMEOUT0x4Установка не подтвержденаРаздел 7
STREAM_CLOSED0x5Получен кадр для завершения потокаРаздел 7
FRAME_SIZE_ERROR0x6Размер кадра некорректенРаздел 7
REFUSED_STREAM0x7Поток не обработанРаздел 7
CANCEL0x8Поток аннулированРаздел 7
COMPRESSION_ERROR0x9Состояние компрессии не обновленоРаздел 7
CONNECT_ERROR0xaОшибка TCP-соединения для метода CONNECTРаздел 7
ENHANCE_YOUR_CALM0xbПревышена емкость для обработкиРаздел 7
INADEQUATE_SECURITY0xcСогласованные параметры TLS не приемлемыРаздел 7
HTTP_1_1_REQUIRED0xdДля запроса используется HTTP/1.1Раздел 7

13. Ссылки

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

  1. [COMPRESSION] Ruellan, H. и R. Peon, “HPACK - Header Compression for HTTP/2”, Internet-Draft draft-ietf-httpbis-header-compression-11 (work in progress), February 2015.
  2. [COOKIE] Barth, A., “HTTP State Management Mechanism”, RFC 6265, April 2011.
  3. [FIPS186] NIST, “Digital Signature Standard (DSS)”, FIPS PUB 186-4, July 2013, .
  4. [RFC2119] Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997.
  5. [RFC2818] Rescorla, E., “HTTP Over TLS”, RFC 2818, May 2000.
  6. [RFC3986] Berners-Lee, T., Fielding, R., и L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax”, STD 66, RFC 3986, January 2005.
  7. [RFC4648] Josefsson, S., “The Base16, Base32, и Base64 Data Encodings”, RFC 4648, October 2006.
  8. [RFC5226] Narten, T. и H. Alvestrand, “Guidelines for Writing an IANA Considerations Раздел in RFCs”, BCP 26, RFC 5226, May 2008.
  9. [RFC5234] Crocker, D. и P. Overell, “Augmented BNF for Syntax Specifications: ABNF”, STD 68, RFC 5234, January 2008.
  10. [RFC7230] Fielding, R., Ed. и J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Message Syntax и Routing”, RFC 7230, June 2014.
  11. [RFC7231] Fielding, R., Ed. и J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Semantics и Content”, RFC 7231, June 2014.
  12. [RFC7232] Fielding, R., Ed. и J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests”, RFC 7232, June 2014.
  13. [RFC7233] Fielding, R., Ed., Lafon, Y., Ed., и J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Range Requests”, RFC 7233, June 2014.
  14. [RFC7234] Fielding, R., Ed., Nottingham, M., Ed., и J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Caching”, RFC 7234, June 2014.
  15. [RFC7235] Fielding, R., Ed. и J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Authentication”, RFC 7235, June 2014.
  16. [TCP] Postel, J., “Transmission Control Protocol”, STD 7, RFC 793, September 1981.
  17. [TLS-ALPN] Friedl, S., Popov, A., Langley, A., и E. Stephan, “Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension”, RFC 7301, July 2014.
  18. [TLS-ECDHE] Rescorla, E., “TLS Elliptic Curve Cipher Suites with SHA-256/384 и AES Galois Counter Mode (GCM)”, RFC 5289, August 2008.
  19. [TLS-EXT] Eastlake, D., “Transport Layer Security (TLS) Extensions: Extension Definitions”, RFC 6066, January 2011.
  20. [TLS12] Dierks, T. и E. Rescorla, “The Transport Layer Security (TLS) Protocol Version 1.2”, RFC 5246, August 2008.

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

  1. [ALT-SVC] Nottingham, M., McManus, P., и J. Reschke, “HTTP Alternative Services”, Internet-Draft draft-ietf-httpbis-alt-svc-06 (work in progress), February 2015.
  2. [BCP90] Klyne, G., Nottingham, M., и J. Mogul, “Registration Procedures for Message Header Fields”, BCP 90, RFC 3864, September 2004.
  3. [BREACH] Gluck, Y., Harris, N., и A. Prado, “BREACH: Reviving the CRIME Attack”, July 2013, .
  4. [HTML5] Hickson, I., Berjon, R., Faulkner, S., Leithead, T., Doyle Navara, E., O'Connor, E., и S. Pfeiffer, “HTML5”, W3C Recommendation REC-html5-20141028, October 2014, . Latest version available at .
  5. [RFC3749] Hollenbeck, S., “Transport Layer Security Protocol Compression Methods”, RFC 3749, May 2004.
  6. [RFC4492] Blake-Wilson, S., Bolyard, N., Gupta, V., Hawk, C., и B. Moeller, “Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)”, RFC 4492, May 2006.
  7. [RFC6585] Nottingham, M. и R. Fielding, “Additional HTTP Status Codes”, RFC 6585, April 2012.
  8. [RFC7323] Borman, D., Braden, B., Jacobson, V., и R. Scheffenegger, “TCP Extensions for High Performance”, RFC 7323, September 2014.
  9. [TALKING] Huang, L-S., Chen, E., Barth, A., Rescorla, E., и C. Jackson, “Talking to Yourself for Fun и Profit”, 2011, .
  10. [TLSBCP] Sheffer, Y., Holz, R., и P. Saint-Andre, “Recommendations for Secure Use of TLS и DTLS”, Internet-Draft draft-ietf-uta-tls-bcp-08 (work in progress), December 2014.

Приложение A. Черный список шифровых наборов TLS 1.2

Реализация HTTP/2 может рассматривать согласование любого из ниже приведенных шифровых наборов с TLS 1.2, как ошибку соединения (Раздел 5.4.1) типа INADEQUATE_SECURITY:

TLS_NULL_WITH_NULL_NULLTLS_RSA_WITH_NULL_MD5
TLS_RSA_WITH_NULL_SHATLS_RSA_EXPORT_WITH_RC4_40_MD5
TLS_RSA_WITH_RC4_128_MD5TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5TLS_RSA_WITH_IDEA_CBC_SHA
TLS_RSA_EXPORT_WITH_DES40_CBC_SHATLS_RSA_WITH_DES_CBC_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHATLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
TLS_DH_DSS_WITH_DES_CBC_SHATLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHATLS_DH_RSA_WITH_DES_CBC_SHA
TLS_DH_RSA_WITH_3DES_EDE_CBC_SHATLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
TLS_DHE_DSS_WITH_DES_CBC_SHATLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHATLS_DHE_RSA_WITH_DES_CBC_SHA
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHATLS_DH_anon_EXPORT_WITH_RC4_40_MD5
TLS_DH_anon_WITH_RC4_128_MD5TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
TLS_DH_anon_WITH_DES_CBC_SHATLS_DH_anon_WITH_3DES_EDE_CBC_SHA
TLS_KRB5_WITH_DES_CBC_SHATLS_KRB5_WITH_3DES_EDE_CBC_SHA
TLS_KRB5_WITH_RC4_128_SHATLS_KRB5_WITH_IDEA_CBC_SHA
TLS_KRB5_WITH_DES_CBC_MD5TLS_KRB5_WITH_3DES_EDE_CBC_MD5
TLS_KRB5_WITH_RC4_128_MD5TLS_KRB5_WITH_IDEA_CBC_MD5
TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHATLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA
TLS_KRB5_EXPORT_WITH_RC4_40_SHATLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5
TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5TLS_KRB5_EXPORT_WITH_RC4_40_MD5
TLS_PSK_WITH_NULL_SHATLS_DHE_PSK_WITH_NULL_SHA
TLS_RSA_PSK_WITH_NULL_SHATLS_RSA_WITH_AES_128_CBC_SHA
TLS_DH_DSS_WITH_AES_128_CBC_SHATLS_DH_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHATLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DH_anon_WITH_AES_128_CBC_SHATLS_RSA_WITH_AES_256_CBC_SHA
TLS_DH_DSS_WITH_AES_256_CBC_SHATLS_DH_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHATLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DH_anon_WITH_AES_256_CBC_SHATLS_RSA_WITH_NULL_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA256TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_DH_DSS_WITH_AES_128_CBC_SHA256TLS_DH_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHATLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA
TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHATLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHATLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_DH_DSS_WITH_AES_256_CBC_SHA256TLS_DH_RSA_WITH_AES_256_CBC_SHA256
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
TLS_DH_anon_WITH_AES_128_CBC_SHA256TLS_DH_anon_WITH_AES_256_CBC_SHA256
TLS_RSA_WITH_CAMELLIA_256_CBC_SHATLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA
TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHATLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHATLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA
TLS_PSK_WITH_RC4_128_SHATLS_PSK_WITH_3DES_EDE_CBC_SHA
TLS_PSK_WITH_AES_128_CBC_SHATLS_PSK_WITH_AES_256_CBC_SHA
TLS_DHE_PSK_WITH_RC4_128_SHATLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
TLS_DHE_PSK_WITH_AES_128_CBC_SHATLS_DHE_PSK_WITH_AES_256_CBC_SHA
TLS_RSA_PSK_WITH_RC4_128_SHATLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
TLS_RSA_PSK_WITH_AES_128_CBC_SHATLS_RSA_PSK_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_SEED_CBC_SHATLS_DH_DSS_WITH_SEED_CBC_SHA
TLS_DH_RSA_WITH_SEED_CBC_SHATLS_DHE_DSS_WITH_SEED_CBC_SHA
TLS_DHE_RSA_WITH_SEED_CBC_SHATLS_DH_anon_WITH_SEED_CBC_SHA
TLS_RSA_WITH_AES_128_GCM_SHA256TLS_RSA_WITH_AES_256_GCM_SHA384
TLS_DH_RSA_WITH_AES_128_GCM_SHA256TLS_DH_RSA_WITH_AES_256_GCM_SHA384
TLS_DH_DSS_WITH_AES_128_GCM_SHA256TLS_DH_DSS_WITH_AES_256_GCM_SHA384
TLS_DH_anon_WITH_AES_128_GCM_SHA256TLS_DH_anon_WITH_AES_256_GCM_SHA384
TLS_PSK_WITH_AES_128_GCM_SHA256TLS_PSK_WITH_AES_256_GCM_SHA384
TLS_RSA_PSK_WITH_AES_128_GCM_SHA256TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
TLS_PSK_WITH_AES_128_CBC_SHA256TLS_PSK_WITH_AES_256_CBC_SHA384
TLS_PSK_WITH_NULL_SHA256TLS_PSK_WITH_NULL_SHA384
TLS_DHE_PSK_WITH_AES_128_CBC_SHA256TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
TLS_DHE_PSK_WITH_NULL_SHA256TLS_DHE_PSK_WITH_NULL_SHA384
TLS_RSA_PSK_WITH_AES_128_CBC_SHA256TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
TLS_RSA_PSK_WITH_NULL_SHA256TLS_RSA_PSK_WITH_NULL_SHA384
TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256
TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256
TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256
TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256
TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256
TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256
TLS_EMPTY_RENEGOTIATION_INFO_SCSVTLS_ECDH_ECDSA_WITH_NULL_SHA
TLS_ECDH_ECDSA_WITH_RC4_128_SHATLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHATLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_NULL_SHATLS_ECDHE_ECDSA_WITH_RC4_128_SHA
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHATLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHATLS_ECDH_RSA_WITH_NULL_SHA
TLS_ECDH_RSA_WITH_RC4_128_SHATLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_RSA_WITH_AES_128_CBC_SHATLS_ECDH_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_NULL_SHATLS_ECDHE_RSA_WITH_RC4_128_SHA
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHATLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHATLS_ECDH_anon_WITH_NULL_SHA
TLS_ECDH_anon_WITH_RC4_128_SHATLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_anon_WITH_AES_128_CBC_SHATLS_ECDH_anon_WITH_AES_256_CBC_SHA
TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHATLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA
TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHATLS_SRP_SHA_WITH_AES_128_CBC_SHA
TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHATLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA
TLS_SRP_SHA_WITH_AES_256_CBC_SHATLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA
TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHATLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384TLS_ECDHE_PSK_WITH_RC4_128_SHA
TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHATLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHATLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384TLS_ECDHE_PSK_WITH_NULL_SHA
TLS_ECDHE_PSK_WITH_NULL_SHA256TLS_ECDHE_PSK_WITH_NULL_SHA384
TLS_RSA_WITH_ARIA_128_CBC_SHA256TLS_RSA_WITH_ARIA_256_CBC_SHA384
TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384
TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384
TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384
TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384
TLS_DH_anon_WITH_ARIA_128_CBC_SHA256TLS_DH_anon_WITH_ARIA_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384
TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384
TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384
TLS_RSA_WITH_ARIA_128_GCM_SHA256TLS_RSA_WITH_ARIA_256_GCM_SHA384
TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384
TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384
TLS_DH_anon_WITH_ARIA_128_GCM_SHA256TLS_DH_anon_WITH_ARIA_256_GCM_SHA384
TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384
TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384
TLS_PSK_WITH_ARIA_128_CBC_SHA256TLS_PSK_WITH_ARIA_256_CBC_SHA384
TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384
TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384
TLS_PSK_WITH_ARIA_128_GCM_SHA256TLS_PSK_WITH_ARIA_256_GCM_SHA384
TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384
TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA25TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384
TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384
TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384
TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
TLS_RSA_WITH_AES_128_CCMTLS_RSA_WITH_AES_256_CCM
TLS_RSA_WITH_AES_128_CCM_8TLS_RSA_WITH_AES_256_CCM_8
TLS_PSK_WITH_AES_128_CCMTLS_PSK_WITH_AES_256_CCM
TLS_PSK_WITH_AES_128_CCM_8TLS_PSK_WITH_AES_256_CCM_8

Previous: 4.5.6.4 Строгая транспортная безопасность HTTP (HSTS - RFC-6797)    UP: 4.5.6 WWW
    Next: 4.5.6.6 HTTP поверх TLS (RFC-2818)