<?xml version="1.0"?> | |
<?xml-stylesheet type="text/xsl" href="lib/rfc2629.xslt"?> | |
<?rfc toc="yes" ?> | |
<?rfc symrefs="yes" ?> | |
<?rfc sortrefs="yes" ?> | |
<?rfc compact="yes"?> | |
<?rfc subcompact="no" ?> | |
<?rfc linkmailto="no" ?> | |
<?rfc editing="no" ?> | |
<?rfc comments="yes" ?> | |
<?rfc inline="yes"?> | |
<?rfc rfcedstyle="yes"?> | |
<?rfc-ext allow-markup-in-artwork="yes" ?> | |
<?rfc-ext include-index="no" ?> | |
<rfc ipr="trust200902" | |
category="std" | |
docName="draft-ietf-httpbis-http2-latest" | |
x:maturity-level="proposed" | |
xmlns:x="http://purl.org/net/xml2rfc/ext"> | |
<x:feedback template="mailto:ietf-http-wg@w3.org?subject={docname},%20%22{section}%22&body=<{ref}>:"/> | |
<front> | |
<title abbrev="HTTP/2">Hypertext Transfer Protocol version 2</title> | |
<author initials="M." surname="Belshe" fullname="Mike Belshe"> | |
<organization>Twist</organization> | |
<address> | |
<email>mbelshe@chromium.org</email> | |
</address> | |
</author> | |
<author initials="R." surname="Peon" fullname="Roberto Peon"> | |
<organization>Google, Inc</organization> | |
<address> | |
<email>fenix@google.com</email> | |
</address> | |
</author> | |
<author initials="M." surname="Thomson" fullname="Martin Thomson" role="editor"> | |
<organization>Mozilla</organization> | |
<address> | |
<postal> | |
<street>331 E Evelyn Street</street> | |
<city>Mountain View</city> | |
<region>CA</region> | |
<code>94041</code> | |
<country>US</country> | |
</postal> | |
<email>martin.thomson@gmail.com</email> | |
</address> | |
</author> | |
<date year="2014" /> | |
<area>Applications</area> | |
<workgroup>HTTPbis</workgroup> | |
<keyword>HTTP</keyword> | |
<keyword>SPDY</keyword> | |
<keyword>Web</keyword> | |
<abstract> | |
<t> | |
This specification describes an optimized expression of the semantics of the Hypertext | |
Transfer Protocol (HTTP). HTTP/2 enables a more efficient use of network resources and a | |
reduced perception of latency by introducing header field compression and allowing multiple | |
concurrent messages on the same connection. It also introduces unsolicited push of | |
representations from servers to clients. | |
</t> | |
<t> | |
This specification is an alternative to, but does not obsolete, the HTTP/1.1 message syntax. | |
HTTP's existing semantics remain unchanged. | |
</t> | |
</abstract> | |
<note title="Editorial Note (To be removed by RFC Editor)"> | |
<t> | |
Discussion of this draft takes place on the HTTPBIS working group mailing list | |
(ietf-http-wg@w3.org), which is archived at <eref | |
target="https://lists.w3.org/Archives/Public/ietf-http-wg/"/>. | |
</t> | |
<t> | |
Working Group information can be found at <eref | |
target="https://tools.ietf.org/wg/httpbis/"/>; that specific to HTTP/2 are at <eref | |
target="https://http2.github.io/"/>. | |
</t> | |
<t> | |
The changes in this draft are summarized in <xref | |
target="change.log"/>. | |
</t> | |
</note> | |
</front> | |
<middle> | |
<section anchor="intro" title="Introduction"> | |
<t> | |
The Hypertext Transfer Protocol (HTTP) is a wildly successful protocol. However, the | |
HTTP/1.1 message format (<xref target="RFC7230" x:fmt="," x:rel="#http.message"/>) has | |
several characteristics that have a negative overall effect on application performance | |
today. | |
</t> | |
<t> | |
In particular, HTTP/1.0 allowed only one request to be outstanding at a time on a given | |
TCP connection. HTTP/1.1 added request pipelining, but this only partially addressed | |
request concurrency and still suffers from head-of-line blocking. Therefore, HTTP/1.1 | |
clients that need to make many requests typically use multiple connections to a server in | |
order to achieve concurrency and thereby reduce latency. | |
</t> | |
<t> | |
Furthermore, HTTP header fields are often repetitive and verbose, causing unnecessary | |
network traffic, as well as causing the initial <xref target="TCP">TCP</xref> congestion | |
window to quickly fill. This can result in excessive latency when multiple requests are | |
made on a new TCP connection. | |
</t> | |
<t> | |
HTTP/2 addresses these issues by defining an optimized mapping of HTTP's semantics to an | |
underlying connection. Specifically, it allows interleaving of request and response | |
messages on the same connection and uses an efficient coding for HTTP header fields. It | |
also allows prioritization of requests, letting more important requests complete more | |
quickly, further improving performance. | |
</t> | |
<t> | |
The resulting protocol is more friendly to the network, because fewer TCP connections can | |
be used in comparison to HTTP/1.x. This means less competition with other flows, and | |
longer-lived connections, which in turn leads to better utilization of available network | |
capacity. | |
</t> | |
<t> | |
Finally, HTTP/2 also enables more efficient processing of messages through use of binary | |
message framing. | |
</t> | |
</section> | |
<section anchor="Overview" title="HTTP/2 Protocol Overview"> | |
<t> | |
HTTP/2 provides an optimized transport for HTTP semantics. HTTP/2 supports all of the core | |
features of HTTP/1.1, but aims to be more efficient in several ways. | |
</t> | |
<t> | |
The basic protocol unit in HTTP/2 is a <xref target="FrameHeader">frame</xref>. Each frame | |
type serves a different purpose. For example, <x:ref>HEADERS</x:ref> and | |
<x:ref>DATA</x:ref> frames form the basis of <xref target="HttpSequence">HTTP requests and | |
responses</xref>; other frame types like <x:ref>SETTINGS</x:ref>, | |
<x:ref>WINDOW_UPDATE</x:ref>, and <x:ref>PUSH_PROMISE</x:ref> are used in support of other | |
HTTP/2 features. | |
</t> | |
<t> | |
Multiplexing of requests is achieved by having each HTTP request-response exchange | |
associated with its own <xref target="StreamsLayer">stream</xref>. Streams are largely | |
independent of each other, so a blocked or stalled request or response does not prevent | |
progress on other streams. | |
</t> | |
<t> | |
Flow control and prioritization ensure that it is possible to efficiently use multiplexed | |
streams. <xref target="FlowControl">Flow control</xref> helps to ensure that only data that | |
can be used by a receiver is transmitted. <xref | |
target="StreamPriority">Prioritization</xref> ensures that limited resources can be directed | |
to the most important streams first. | |
</t> | |
<t> | |
HTTP/2 adds a new interaction mode, whereby a server can <xref target="PushResources">push | |
responses to a client</xref>. Server push allows a server to speculatively send a client | |
data that the server anticipates the client will need, trading off some network usage | |
against a potential latency gain. The server does this by synthesizing a request, which it | |
sends as a <x:ref>PUSH_PROMISE</x:ref> frame. The server is then able to send a response to | |
the synthetic request on a separate stream. | |
</t> | |
<t> | |
Frames that contain HTTP header fields are <xref target="HeaderBlock">compressed</xref>. | |
HTTP requests can be highly redundant, so compression can reduce the size of requests and | |
responses significantly. | |
</t> | |
<section title="Document Organization"> | |
<t> | |
The HTTP/2 specification is split into four parts: | |
<list style="symbols"> | |
<t> | |
<xref target="starting">Starting HTTP/2</xref> covers how an HTTP/2 connection is | |
initiated. | |
</t> | |
<t> | |
The <xref target="FramingLayer">framing</xref> and <xref | |
target="StreamsLayer">streams</xref> layers describe the way HTTP/2 frames are | |
structured and formed into multiplexed streams. | |
</t> | |
<t> | |
<xref target="FrameTypes">Frame</xref> and <xref target="ErrorCodes">error</xref> | |
definitions include details of the frame and error types used in HTTP/2. | |
</t> | |
<t> | |
<xref target="HTTPLayer">HTTP mappings</xref> and <xref target="HttpExtra">additional | |
requirements</xref> describe how HTTP semantics are expressed using frames and | |
streams. | |
</t> | |
</list> | |
</t> | |
<t> | |
While some of the frame and stream layer concepts are isolated from HTTP, this | |
specification does not define a completely generic framing layer. The framing and streams | |
layers are tailored to the needs of the HTTP protocol and server push. | |
</t> | |
</section> | |
<section title="Conventions and Terminology"> | |
<t> | |
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD | |
NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as | |
described in <xref target="RFC2119">RFC 2119</xref>. | |
</t> | |
<t> | |
All numeric values are in network byte order. Values are unsigned unless otherwise | |
indicated. Literal values are provided in decimal or hexadecimal as appropriate. | |
Hexadecimal literals are prefixed with <spanx style="verb">0x</spanx> to distinguish them | |
from decimal literals. | |
</t> | |
<t> | |
The following terms are used: | |
<list style="hanging"> | |
<t hangText="client:"> | |
The endpoint initiating the HTTP/2 connection. | |
</t> | |
<t hangText="connection:"> | |
A transport-layer connection between two endpoints. | |
</t> | |
<t hangText="connection error:"> | |
An error that affects the entire HTTP/2 connection. | |
</t> | |
<t hangText="endpoint:"> | |
Either the client or server of the connection. | |
</t> | |
<t hangText="frame:"> | |
The smallest unit of communication within an HTTP/2 connection, consisting of a header | |
and a variable-length sequence of octets structured according to the frame type. | |
</t> | |
<t hangText="peer:"> | |
An endpoint. When discussing a particular endpoint, "peer" refers to the endpoint | |
that is remote to the primary subject of discussion. | |
</t> | |
<t hangText="receiver:"> | |
An endpoint that is receiving frames. | |
</t> | |
<t hangText="sender:"> | |
An endpoint that is transmitting frames. | |
</t> | |
<t hangText="server:"> | |
The endpoint which did not initiate the HTTP/2 connection. | |
</t> | |
<t hangText="stream:"> | |
A bi-directional flow of frames across a virtual channel within the HTTP/2 connection. | |
</t> | |
<t hangText="stream error:"> | |
An error on the individual HTTP/2 stream. | |
</t> | |
</list> | |
</t> | |
<t> | |
Finally, the terms "gateway", "intermediary", "proxy", and "tunnel" are defined | |
in <xref target="RFC7230" x:fmt="of" x:rel="#intermediaries"/>. | |
</t> | |
</section> | |
</section> | |
<section anchor="starting" title="Starting HTTP/2"> | |
<t> | |
An HTTP/2 connection is an application layer protocol running on top of a TCP connection | |
(<xref target="TCP"/>). The client is the TCP connection initiator. | |
</t> | |
<t> | |
HTTP/2 uses the same "http" and "https" URI schemes used by HTTP/1.1. HTTP/2 shares the same | |
default port numbers: 80 for "http" URIs and 443 for "https" URIs. As a result, | |
implementations processing requests for target resource URIs like <spanx | |
style="verb">http://example.org/foo</spanx> or <spanx | |
style="verb">https://example.com/bar</spanx> are required to first discover whether the | |
upstream server (the immediate peer to which the client wishes to establish a connection) | |
supports HTTP/2. | |
</t> | |
<t> | |
The means by which support for HTTP/2 is determined is different for "http" and "https" | |
URIs. Discovery for "http" URIs is described in <xref target="discover-http"/>. Discovery | |
for "https" URIs is described in <xref target="discover-https"/>. | |
</t> | |
<section anchor="versioning" title="HTTP/2 Version Identification"> | |
<t> | |
The protocol defined in this document has two identifiers. | |
<list style="symbols"> | |
<x:lt> | |
<t> | |
The string "h2" identifies the protocol where HTTP/2 uses <xref | |
target="TLS12">TLS</xref>. This identifier is used in the <xref | |
target="TLS-ALPN">TLS application layer protocol negotiation extension (ALPN)</xref> | |
field and any place that HTTP/2 over TLS is identified. | |
</t> | |
<t> | |
The "h2" string is serialized into an ALPN protocol identifier as the two octet | |
sequence: 0x68, 0x32. | |
</t> | |
</x:lt> | |
<x:lt> | |
<t> | |
The string "h2c" identifies the protocol where HTTP/2 is run over cleartext TCP. | |
This identifier is used in the HTTP/1.1 Upgrade header field and any place that | |
HTTP/2 over TCP is identified. | |
</t> | |
</x:lt> | |
</list> | |
</t> | |
<t> | |
Negotiating "h2" or "h2c" implies the use of the transport, security, framing and message | |
semantics described in this document. | |
</t> | |
<t> | |
<cref>RFC Editor's Note: please remove the remainder of this section prior to the | |
publication of a final version of this document.</cref> | |
</t> | |
<t> | |
Only implementations of the final, published RFC can identify themselves as "h2" or "h2c". | |
Until such an RFC exists, implementations MUST NOT identify themselves using these | |
strings. | |
</t> | |
<t> | |
Examples and text throughout the rest of this document use "h2" as a matter of | |
editorial convenience only. Implementations of draft versions MUST NOT identify using | |
this string. | |
</t> | |
<t> | |
Implementations of draft versions of the protocol MUST add the string "-" and the | |
corresponding draft number to the identifier. For example, draft-ietf-httpbis-http2-11 | |
over TLS is identified using the string "h2-11". | |
</t> | |
<t> | |
Non-compatible experiments that are based on these draft versions MUST append the string | |
"-" and an experiment name to the identifier. For example, an experimental implementation | |
of packet mood-based encoding based on draft-ietf-httpbis-http2-09 might identify itself | |
as "h2-09-emo". Note that any label MUST conform to the "token" syntax defined in | |
<xref target="RFC7230" x:fmt="of" x:rel="#field.components"/>. Experimenters are | |
encouraged to coordinate their experiments on the ietf-http-wg@w3.org mailing list. | |
</t> | |
</section> | |
<section anchor="discover-http" title="Starting HTTP/2 for "http" URIs"> | |
<t> | |
A client that makes a request for an "http" URI without prior knowledge about support for | |
HTTP/2 uses the HTTP Upgrade mechanism (<xref target="RFC7230" x:fmt="of" | |
x:rel="#header.upgrade"/>). The client makes an HTTP/1.1 request that includes an Upgrade | |
header field identifying HTTP/2 with the "h2c" token. The HTTP/1.1 request MUST include | |
exactly one <xref target="Http2SettingsHeader">HTTP2-Settings</xref> header field. | |
</t> | |
<figure> | |
<preamble>For example:</preamble> | |
<artwork type="message/http; msgtype="request"" x:indent-with=" "><![CDATA[ | |
GET / HTTP/1.1 | |
Host: server.example.com | |
Connection: Upgrade, HTTP2-Settings | |
Upgrade: h2c | |
HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload> | |
]]></artwork> | |
</figure> | |
<t> | |
Requests that contain an entity body MUST be sent in their entirety before the client can | |
send HTTP/2 frames. This means that a large request entity can block the use of the | |
connection until it is completely sent. | |
</t> | |
<t> | |
If concurrency of an initial request with subsequent requests is important, an OPTIONS | |
request can be used to perform the upgrade to HTTP/2, at the cost of an additional | |
round-trip. | |
</t> | |
<t> | |
A server that does not support HTTP/2 can respond to the request as though the Upgrade | |
header field were absent: | |
</t> | |
<figure> | |
<artwork type="message/http; msgtype="response"" x:indent-with=" "> | |
HTTP/1.1 200 OK | |
Content-Length: 243 | |
Content-Type: text/html | |
... | |
</artwork> | |
</figure> | |
<t> | |
A server MUST ignore a "h2" token in an Upgrade header field. Presence of a token with | |
"h2" implies HTTP/2 over TLS, which is instead negotiated as described in <xref | |
target="discover-https"/>. | |
</t> | |
<t> | |
A server that supports HTTP/2 can accept the upgrade with a 101 (Switching Protocols) | |
response. After the empty line that terminates the 101 response, the server can begin | |
sending HTTP/2 frames. These frames MUST include a response to the request that initiated | |
the Upgrade. | |
</t> | |
<figure> | |
<preamble> | |
For example: | |
</preamble> | |
<artwork type="message/http; msgtype="response"" x:indent-with=" "> | |
HTTP/1.1 101 Switching Protocols | |
Connection: Upgrade | |
Upgrade: h2c | |
[ HTTP/2 connection ... | |
</artwork> | |
</figure> | |
<t> | |
The first HTTP/2 frame sent by the server is a <x:ref>SETTINGS</x:ref> frame (<xref | |
target="SETTINGS"/>) as the server connection preface (<xref | |
target="ConnectionHeader"/>). Upon receiving the 101 response, the client sends a <xref | |
target="ConnectionHeader">connection preface</xref>, which includes a | |
<x:ref>SETTINGS</x:ref> frame. | |
</t> | |
<t> | |
The HTTP/1.1 request that is sent prior to upgrade is assigned stream identifier 1 and is | |
assigned <xref target="pri-default">default priority values</xref>. Stream 1 is | |
implicitly half closed from the client toward the server, since the request is completed | |
as an HTTP/1.1 request. After commencing the HTTP/2 connection, stream 1 is used for the | |
response. | |
</t> | |
<section anchor="Http2SettingsHeader" title="HTTP2-Settings Header Field"> | |
<t> | |
A request that upgrades from HTTP/1.1 to HTTP/2 MUST include exactly one <spanx | |
style="verb">HTTP2-Settings</spanx> header field. The <spanx | |
style="verb">HTTP2-Settings</spanx> header field is a connection-specific header field | |
that includes parameters that govern the HTTP/2 connection, provided in anticipation of | |
the server accepting the request to upgrade. | |
</t> | |
<figure> | |
<artwork type="abnf" x:indent-with=" "><![CDATA[ | |
HTTP2-Settings = token68 | |
]]></artwork> | |
</figure> | |
<t> | |
A server MUST NOT upgrade the connection to HTTP/2 if this header field is not present, | |
or if more than one is present. A server MUST NOT send this header field. | |
</t> | |
<t> | |
The content of the <spanx style="verb">HTTP2-Settings</spanx> header field is the | |
payload of a <x:ref>SETTINGS</x:ref> frame (<xref target="SETTINGS"/>), encoded as a | |
base64url string (that is, the URL- and filename-safe Base64 encoding described in <xref | |
target="RFC4648" x:fmt="of" x:sec="5"/>, with any trailing '=' characters omitted). The | |
<xref target="RFC5234">ABNF</xref> production for <spanx style="verb">token68</spanx> is | |
defined in <xref target="RFC7235" x:fmt="of" x:rel="#challenge.and.response"/>. | |
</t> | |
<t> | |
Since the upgrade is only intended to apply to the immediate connection, a client | |
sending <spanx style="verb">HTTP2-Settings</spanx> MUST also send <spanx | |
style="verb">HTTP2-Settings</spanx> as a connection option in the <spanx | |
style="verb">Connection</spanx> header field to prevent it from being forwarded | |
downstream. | |
</t> | |
<t> | |
A server decodes and interprets these values as it would any other | |
<x:ref>SETTINGS</x:ref> frame. <xref target="SettingsSync">Acknowledgement of the | |
SETTINGS parameters</xref> is not necessary, since a 101 response serves as implicit | |
acknowledgment. Providing these values in the Upgrade request gives a client an | |
opportunity to provide parameters prior to receiving any frames from the server. | |
</t> | |
</section> | |
</section> | |
<section anchor="discover-https" title="Starting HTTP/2 for "https" URIs"> | |
<t> | |
A client that makes a request to an "https" URI uses <xref target="TLS12">TLS</xref> | |
with the <xref target="TLS-ALPN">application layer protocol negotiation extension</xref>. | |
</t> | |
<t> | |
HTTP/2 over TLS uses the "h2" application token. The "h2c" token MUST NOT be sent by a | |
client or selected by a server. | |
</t> | |
<t> | |
Once TLS negotiation is complete, both the client and the server send a <xref | |
target="ConnectionHeader">connection preface</xref>. | |
</t> | |
</section> | |
<section anchor="known-http" title="Starting HTTP/2 with Prior Knowledge"> | |
<t> | |
A client can learn that a particular server supports HTTP/2 by other means. For example, | |
<xref target="ALT-SVC"/> describes a mechanism for advertising this capability. | |
</t> | |
<t> | |
A client MAY immediately send HTTP/2 frames to a server that is known to support HTTP/2, | |
after the <xref target="ConnectionHeader">connection preface</xref>; a server can | |
identify such a connection by the presence of the connection preface. This only affects | |
the establishment of HTTP/2 connections over cleartext TCP; implementations that support | |
HTTP/2 over TLS MUST use <xref target="TLS-ALPN">protocol negotiation in TLS</xref>. | |
</t> | |
<t> | |
Without additional information, prior support for HTTP/2 is not a strong signal that a | |
given server will support HTTP/2 for future connections. For example, it is possible for | |
server configurations to change, for configurations to differ between instances in | |
clustered servers, or for network conditions to change. | |
</t> | |
</section> | |
<section anchor="ConnectionHeader" title="HTTP/2 Connection Preface"> | |
<t> | |
Upon establishment of a TCP connection and determination that HTTP/2 will be used by both | |
peers, each endpoint MUST send a connection preface as a final confirmation and to | |
establish the initial SETTINGS parameters for the HTTP/2 connection. The client and | |
server each send a different connection preface. | |
</t> | |
<t> | |
The client connection preface starts with a sequence of 24 octets, which in hex notation | |
are: | |
</t> | |
<figure> | |
<artwork type="inline" x:indent-with=" "><![CDATA[ | |
0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a | |
]]></artwork> | |
</figure> | |
<t> | |
(the string <spanx style="verb">PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n</spanx>). This sequence | |
is followed by a <x:ref>SETTINGS</x:ref> frame (<xref target="SETTINGS"/>). The | |
<x:ref>SETTINGS</x:ref> frame MAY be empty. The client sends the client connection | |
preface immediately upon receipt of a 101 Switching Protocols response (indicating a | |
successful upgrade), or as the first application data octets of a TLS connection. If | |
starting an HTTP/2 connection with prior knowledge of server support for the protocol, the | |
client connection preface is sent upon connection establishment. | |
</t> | |
<t> | |
<list> | |
<t> | |
The client connection preface is selected so that a large proportion of HTTP/1.1 or | |
HTTP/1.0 servers and intermediaries do not attempt to process further frames. Note | |
that this does not address the concerns raised in <xref target="TALKING"/>. | |
</t> | |
</list> | |
</t> | |
<t> | |
The server connection preface consists of a potentially empty <x:ref>SETTINGS</x:ref> | |
frame (<xref target="SETTINGS"/>) that MUST be the first frame the server sends in the | |
HTTP/2 connection. | |
</t> | |
<t> | |
The <x:ref>SETTINGS</x:ref> frames received from a peer as part of the connection preface | |
MUST be acknowledged (see <xref target="SettingsSync"/>) after sending the connection | |
preface. | |
</t> | |
<t> | |
To avoid unnecessary latency, clients are permitted to send additional frames to the | |
server immediately after sending the client connection preface, without waiting to receive | |
the server connection preface. It is important to note, however, that the server | |
connection preface <x:ref>SETTINGS</x:ref> frame might include parameters that necessarily | |
alter how a client is expected to communicate with the server. Upon receiving the | |
<x:ref>SETTINGS</x:ref> frame, the client is expected to honor any parameters established. | |
In some configurations, it is possible for the server to transmit <x:ref>SETTINGS</x:ref> | |
before the client sends additional frames, providing an opportunity to avoid this issue. | |
</t> | |
<t> | |
Clients and servers MUST treat an invalid connection preface as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. A <x:ref>GOAWAY</x:ref> frame (<xref target="GOAWAY"/>) | |
MAY be omitted in this case, since an invalid preface indicates that the peer is not using | |
HTTP/2. | |
</t> | |
</section> | |
</section> | |
<section anchor="FramingLayer" title="HTTP Frames"> | |
<t> | |
Once the HTTP/2 connection is established, endpoints can begin exchanging frames. | |
</t> | |
<section anchor="FrameHeader" title="Frame Format"> | |
<t> | |
All frames begin with a fixed 9-octet header followed by a variable-length payload. | |
</t> | |
<figure title="Frame Layout"> | |
<artwork type="inline"><![CDATA[ | |
0 1 2 3 | |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| Length (24) | | |
+---------------+---------------+---------------+ | |
| Type (8) | Flags (8) | | |
+-+-+-----------+---------------+-------------------------------+ | |
|R| Stream Identifier (31) | | |
+=+=============================================================+ | |
| Frame Payload (0...) ... | |
+---------------------------------------------------------------+ | |
]]></artwork> | |
</figure> | |
<t> | |
The fields of the frame header are defined as: | |
<list style="hanging"> | |
<x:lt hangText="Length:"> | |
<t> | |
The length of the frame payload expressed as an unsigned 24-bit integer. Values | |
greater than 2<x:sup>14</x:sup> (16,384) MUST NOT be sent unless the receiver has | |
set a larger value for <x:ref>SETTINGS_MAX_FRAME_SIZE</x:ref>. | |
</t> | |
<t> | |
The 9 octets of the frame header are not included in this value. | |
</t> | |
</x:lt> | |
<x:lt hangText="Type:"> | |
<t> | |
The 8-bit type of the frame. The frame type determines the format and semantics of | |
the frame. Implementations MUST ignore and discard any frame that has a type that | |
is unknown. | |
</t> | |
</x:lt> | |
<x:lt hangText="Flags:"> | |
<t> | |
An 8-bit field reserved for frame-type specific boolean flags. | |
</t> | |
<t> | |
Flags are assigned semantics specific to the indicated frame type. Flags that have | |
no defined semantics for a particular frame type MUST be ignored, and MUST be left | |
unset (0) when sending. | |
</t> | |
</x:lt> | |
<x:lt hangText="R:"> | |
<t> | |
A reserved 1-bit field. The semantics of this bit are undefined and the bit MUST | |
remain unset (0) when sending and MUST be ignored when receiving. | |
</t> | |
</x:lt> | |
<x:lt hangText="Stream Identifier:"> | |
<t> | |
A 31-bit stream identifier (see <xref target="StreamIdentifiers"/>). The value 0 is | |
reserved for frames that are associated with the connection as a whole as opposed to | |
an individual stream. | |
</t> | |
</x:lt> | |
</list> | |
</t> | |
<t> | |
The structure and content of the frame payload is dependent entirely on the frame type. | |
</t> | |
</section> | |
<section anchor="FrameSize" title="Frame Size"> | |
<t> | |
The size of a frame payload is limited by the maximum size that a receiver advertises in | |
the <x:ref>SETTINGS_MAX_FRAME_SIZE</x:ref> setting. This setting can have any value | |
between 2<x:sup>14</x:sup> (16,384) and 2<x:sup>24</x:sup>-1 (16,777,215) octets, | |
inclusive. | |
</t> | |
<t> | |
All implementations MUST be capable of receiving and minimally processing frames up to | |
2<x:sup>14</x:sup> octets in length, plus the 9 octet <xref target="FrameHeader">frame | |
header</xref>. The size of the frame header is not included when describing frame sizes. | |
<list style="hanging"> | |
<t hangText="Note:"> | |
Certain frame types, such as <xref target="PING">PING</xref>, impose additional limits | |
on the amount of payload data allowed. | |
</t> | |
</list> | |
</t> | |
<t> | |
If a frame size exceeds any defined limit, or is too small to contain mandatory frame | |
data, the endpoint MUST send a <x:ref>FRAME_SIZE_ERROR</x:ref> error. A frame size error | |
in a frame that could alter the state of the entire connection MUST be treated as a <xref | |
target="ConnectionErrorHandler">connection error</xref>; this includes any frame carrying | |
a <xref target="HeaderBlock">header block</xref> (that is, <x:ref>HEADERS</x:ref>, | |
<x:ref>PUSH_PROMISE</x:ref>, and <x:ref>CONTINUATION</x:ref>), <x:ref>SETTINGS</x:ref>, | |
and any <x:ref>WINDOW_UPDATE</x:ref> frame with a stream identifier of 0. | |
</t> | |
<t> | |
Endpoints are not obligated to use all available space in a frame. Responsiveness can be | |
improved by using frames that are smaller than the permitted maximum size. Sending large | |
frames can result in delays in sending time-sensitive frames (such | |
<x:ref>RST_STREAM</x:ref>, <x:ref>WINDOW_UPDATE</x:ref>, or <x:ref>PRIORITY</x:ref>) | |
which if blocked by the transmission of a large frame, could affect performance. | |
</t> | |
</section> | |
<section anchor="HeaderBlock" title="Header Compression and Decompression"> | |
<t> | |
Just as in HTTP/1, a header field in HTTP/2 is a name with one or more associated values. | |
They are used within HTTP request and response messages as well as server push operations | |
(see <xref target="PushResources" />). | |
</t> | |
<t> | |
Header lists are collections of zero or more header fields. When transmitted over a | |
connection, a header list is serialized into a header block using <xref | |
target="COMPRESSION">HTTP Header Compression</xref>. The serialized header block is then | |
divided into one or more octet sequences, called header block fragments, and transmitted | |
within the payload of <xref target="HEADERS">HEADERS</xref>, <xref | |
target="PUSH_PROMISE">PUSH_PROMISE</xref> or <xref | |
target="CONTINUATION">CONTINUATION</xref> frames. | |
</t> | |
<t> | |
The <xref target="COOKIE">Cookie header field</xref> is treated specially by the HTTP | |
mapping (see <xref target="CompressCookie"/>). | |
</t> | |
<t> | |
A receiving endpoint reassembles the header block by concatenating its fragments, then | |
decompresses the block to reconstruct the header list. | |
</t> | |
<t> | |
A complete header block consists of either: | |
<list style="symbols"> | |
<t> | |
a single <x:ref>HEADERS</x:ref> or <x:ref>PUSH_PROMISE</x:ref> frame, | |
with the END_HEADERS flag set, or | |
</t> | |
<t> | |
a <x:ref>HEADERS</x:ref> or <x:ref>PUSH_PROMISE</x:ref> frame with the END_HEADERS | |
flag cleared and one or more <x:ref>CONTINUATION</x:ref> frames, | |
where the last <x:ref>CONTINUATION</x:ref> frame has the END_HEADERS flag set. | |
</t> | |
</list> | |
</t> | |
<t> | |
Header compression is stateful. One compression context and one decompression context is | |
used for the entire connection. Each header block is processed as a discrete unit. | |
Header blocks MUST be transmitted as a contiguous sequence of frames, with no interleaved | |
frames of any other type or from any other stream. The last frame in a sequence of | |
<x:ref>HEADERS</x:ref> or <x:ref>CONTINUATION</x:ref> frames MUST have the END_HEADERS | |
flag set. The last frame in a sequence of <x:ref>PUSH_PROMISE</x:ref> or | |
<x:ref>CONTINUATION</x:ref> frames MUST have the END_HEADERS flag set. This allows a | |
header block to be logically equivalent to a single frame. | |
</t> | |
<t> | |
Header block fragments can only be sent as the payload of <x:ref>HEADERS</x:ref>, | |
<x:ref>PUSH_PROMISE</x:ref> or <x:ref>CONTINUATION</x:ref> frames, because these frames | |
carry data that can modify the compression context maintained by a receiver. An endpoint | |
receiving <x:ref>HEADERS</x:ref>, <x:ref>PUSH_PROMISE</x:ref> or | |
<x:ref>CONTINUATION</x:ref> frames MUST reassemble header blocks and perform decompression | |
even if the frames are to be discarded. A receiver MUST terminate the connection with a | |
<xref target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>COMPRESSION_ERROR</x:ref> if it does not decompress a header block. | |
</t> | |
</section> | |
</section> | |
<section anchor="StreamsLayer" title="Streams and Multiplexing"> | |
<t> | |
A "stream" is an independent, bi-directional sequence of frames exchanged between the client | |
and server within an HTTP/2 connection. Streams have several important characteristics: | |
<list style="symbols"> | |
<t> | |
A single HTTP/2 connection can contain multiple concurrently open streams, with either | |
endpoint interleaving frames from multiple streams. | |
</t> | |
<t> | |
Streams can be established and used unilaterally or shared by either the client or | |
server. | |
</t> | |
<t> | |
Streams can be closed by either endpoint. | |
</t> | |
<t> | |
The order in which frames are sent on a stream is significant. Recipients process frames | |
in the order they are received. In particular, the order of <x:ref>HEADERS</x:ref>, | |
and <x:ref>DATA</x:ref> frames is semantically significant. | |
</t> | |
<t> | |
Streams are identified by an integer. Stream identifiers are assigned to streams by the | |
endpoint initiating the stream. | |
</t> | |
</list> | |
</t> | |
<section anchor="StreamStates" title="Stream States"> | |
<t> | |
The lifecycle of a stream is shown in <xref target="StreamStatesFigure"/>. | |
</t> | |
<figure anchor="StreamStatesFigure" title="Stream States"> | |
<artwork type="drawing"> | |
<![CDATA[ | |
+--------+ | |
PP | | PP | |
,--------| idle |--------. | |
/ | | \ | |
v +--------+ v | |
+----------+ | +----------+ | |
| | | H | | | |
,---| reserved | | | reserved |---. | |
| | (local) | v | (remote) | | | |
| +----------+ +--------+ +----------+ | | |
| | ES | | ES | | | |
| | H ,-------| open |-------. | H | | |
| | / | | \ | | | |
| v v +--------+ v v | | |
| +----------+ | +----------+ | | |
| | half | | | half | | | |
| | closed | | R | closed | | | |
| | (remote) | | | (local) | | | |
| +----------+ | +----------+ | | |
| | v | | | |
| | ES / R +--------+ ES / R | | | |
| `----------->| |<-----------' | | |
| R | closed | R | | |
`-------------------->| |<--------------------' | |
+--------+ | |
H: HEADERS frame (with implied CONTINUATIONs) | |
PP: PUSH_PROMISE frame (with implied CONTINUATIONs) | |
ES: END_STREAM flag | |
R: RST_STREAM frame | |
]]> | |
</artwork> | |
</figure> | |
<t> | |
Note that this diagram shows stream state transitions and the frames and flags that affect | |
those transitions only. In this regard, <x:ref>CONTINUATION</x:ref> frames do not result | |
in state transitions; they are effectively part of the <x:ref>HEADERS</x:ref> or | |
<x:ref>PUSH_PROMISE</x:ref> that they follow. For this purpose, the END_STREAM flag is | |
processed as a separate event to the frame that bears it; a <x:ref>HEADERS</x:ref> frame | |
with the END_STREAM flag set can cause two state transitions. | |
</t> | |
<t> | |
Both endpoints have a subjective view of the state of a stream that could be different | |
when frames are in transit. Endpoints do not coordinate the creation of streams; they are | |
created unilaterally by either endpoint. The negative consequences of a mismatch in | |
states are limited to the "closed" state after sending <x:ref>RST_STREAM</x:ref>, where | |
frames might be received for some time after closing. | |
</t> | |
<t> | |
Streams have the following states: | |
<list style="hanging"> | |
<x:lt hangText="idle:"> | |
<t> | |
<vspace blankLines="0"/> | |
All streams start in the "idle" state. In this state, no frames have been | |
exchanged. | |
</t> | |
<t> | |
The following transitions are valid from this state: | |
<list style="symbols"> | |
<t> | |
Sending or receiving a <x:ref>HEADERS</x:ref> frame causes the stream to become | |
"open". The stream identifier is selected as described in <xref | |
target="StreamIdentifiers"/>. The same <x:ref>HEADERS</x:ref> frame can also | |
cause a stream to immediately become "half closed". | |
</t> | |
<t> | |
Sending a <x:ref>PUSH_PROMISE</x:ref> frame marks the associated stream for | |
later use. The stream state for the reserved stream transitions to "reserved | |
(local)". | |
</t> | |
<t> | |
Receiving a <x:ref>PUSH_PROMISE</x:ref> frame marks the associated stream as | |
reserved by the remote peer. The state of the stream becomes "reserved | |
(remote)". | |
</t> | |
</list> | |
</t> | |
<t> | |
Receiving any frames other than <x:ref>HEADERS</x:ref> or | |
<x:ref>PUSH_PROMISE</x:ref> on a stream in this state MUST be treated as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
</x:lt> | |
<x:lt hangText="reserved (local):"> | |
<t> | |
<vspace blankLines="0"/> | |
A stream in the "reserved (local)" state is one that has been promised by sending a | |
<x:ref>PUSH_PROMISE</x:ref> frame. A <x:ref>PUSH_PROMISE</x:ref> frame reserves an | |
idle stream by associating the stream with an open stream that was initiated by the | |
remote peer (see <xref target="PushResources"/>). | |
</t> | |
<t> | |
In this state, only the following transitions are possible: | |
<list style="symbols"> | |
<t> | |
The endpoint can send a <x:ref>HEADERS</x:ref> frame. This causes the stream to | |
open in a "half closed (remote)" state. | |
</t> | |
<t> | |
Either endpoint can send a <x:ref>RST_STREAM</x:ref> frame to cause the stream | |
to become "closed". This releases the stream reservation. | |
</t> | |
</list> | |
</t> | |
<t> | |
An endpoint MUST NOT send any type of frame other than <x:ref>HEADERS</x:ref> or | |
<x:ref>RST_STREAM</x:ref> in this state. | |
</t> | |
<t> | |
A <x:ref>PRIORITY</x:ref> frame MAY be received in this state. Receiving any type | |
of frame other than <x:ref>RST_STREAM</x:ref> or <x:ref>PRIORITY</x:ref> on a stream | |
in this state MUST be treated as a <xref target="ConnectionErrorHandler">connection | |
error</xref> of type <x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
</x:lt> | |
<x:lt hangText="reserved (remote):"> | |
<t> | |
<vspace blankLines="0"/> | |
A stream in the "reserved (remote)" state has been reserved by a remote peer. | |
</t> | |
<t> | |
In this state, only the following transitions are possible: | |
<list style="symbols"> | |
<t> | |
Receiving a <x:ref>HEADERS</x:ref> frame causes the stream to transition to | |
"half closed (local)". | |
</t> | |
<t> | |
Either endpoint can send a <x:ref>RST_STREAM</x:ref> frame to cause the stream | |
to become "closed". This releases the stream reservation. | |
</t> | |
</list> | |
</t> | |
<t> | |
An endpoint MAY send a <x:ref>PRIORITY</x:ref> frame in this state to reprioritize | |
the reserved stream. An endpoint MUST NOT send any type of frame other than | |
<x:ref>RST_STREAM</x:ref>, <x:ref>WINDOW_UPDATE</x:ref>, or <x:ref>PRIORITY</x:ref> | |
in this state. | |
</t> | |
<t> | |
Receiving any type of frame other than <x:ref>HEADERS</x:ref> or | |
<x:ref>RST_STREAM</x:ref> on a stream in this state MUST be treated as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
</x:lt> | |
<x:lt hangText="open:"> | |
<t> | |
<vspace blankLines="0"/> | |
A stream in the "open" state may be used by both peers to send frames of any type. | |
In this state, sending peers observe advertised <xref target="FlowControl">stream | |
level flow control limits</xref>. | |
</t> | |
<t> | |
From this state either endpoint can send a frame with an END_STREAM flag set, which | |
causes the stream to transition into one of the "half closed" states: an endpoint | |
sending an END_STREAM flag causes the stream state to become "half closed (local)"; | |
an endpoint receiving an END_STREAM flag causes the stream state to become "half | |
closed (remote)". | |
</t> | |
<t> | |
Either endpoint can send a <x:ref>RST_STREAM</x:ref> frame from this state, causing | |
it to transition immediately to "closed". | |
</t> | |
</x:lt> | |
<x:lt hangText="half closed (local):"> | |
<t> | |
<vspace blankLines="0"/> | |
A stream that is in the "half closed (local)" state cannot be used for sending | |
frames. Only <x:ref>WINDOW_UPDATE</x:ref>, <x:ref>PRIORITY</x:ref> and | |
<x:ref>RST_STREAM</x:ref> frames can be sent in this state. | |
</t> | |
<t> | |
A stream transitions from this state to "closed" when a frame that contains an | |
END_STREAM flag is received, or when either peer sends a <x:ref>RST_STREAM</x:ref> | |
frame. | |
</t> | |
<t> | |
A receiver can ignore <x:ref>WINDOW_UPDATE</x:ref> frames in this state, which might | |
arrive for a short period after a frame bearing the END_STREAM flag is sent. | |
</t> | |
<t> | |
<x:ref>PRIORITY</x:ref> frames received in this state are used to reprioritize | |
streams that depend on the current stream. | |
</t> | |
</x:lt> | |
<x:lt hangText="half closed (remote):"> | |
<t> | |
<vspace blankLines="0"/> | |
A stream that is "half closed (remote)" is no longer being used by the peer to send | |
frames. In this state, an endpoint is no longer obligated to maintain a receiver | |
flow control window if it performs flow control. | |
</t> | |
<t> | |
If an endpoint receives additional frames for a stream that is in this state, other | |
than <x:ref>WINDOW_UPDATE</x:ref>, <x:ref>PRIORITY</x:ref> or | |
<x:ref>RST_STREAM</x:ref>, it MUST respond with a <xref | |
target="StreamErrorHandler">stream error</xref> of type | |
<x:ref>STREAM_CLOSED</x:ref>. | |
</t> | |
<t> | |
A stream that is "half closed (remote)" can be used by the endpoint to send frames | |
of any type. In this state, the endpoint continues to observe advertised <xref | |
target="FlowControl">stream level flow control limits</xref>. | |
</t> | |
<t> | |
A stream can transition from this state to "closed" by sending a frame that contains | |
an END_STREAM flag, or when either peer sends a <x:ref>RST_STREAM</x:ref> frame. | |
</t> | |
</x:lt> | |
<x:lt hangText="closed:"> | |
<t> | |
<vspace blankLines="0"/> | |
The "closed" state is the terminal state. | |
</t> | |
<t> | |
An endpoint MUST NOT send frames other than <x:ref>PRIORITY</x:ref> on a closed | |
stream. An endpoint that receives any frame other than <x:ref>PRIORITY</x:ref> | |
after receiving a <x:ref>RST_STREAM</x:ref> MUST treat that as a <xref | |
target="StreamErrorHandler">stream error</xref> of type | |
<x:ref>STREAM_CLOSED</x:ref>. Similarly, an endpoint that receives any frames after | |
receiving a frame with the END_STREAM flag set MUST treat that as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>STREAM_CLOSED</x:ref>, unless the frame is permitted as described below. | |
</t> | |
<t> | |
<x:ref>WINDOW_UPDATE</x:ref> or <x:ref>RST_STREAM</x:ref> frames can be received in | |
this state for a short period after a <x:ref>DATA</x:ref> or <x:ref>HEADERS</x:ref> | |
frame containing an END_STREAM flag is sent. Until the remote peer receives and | |
processes <x:ref>RST_STREAM</x:ref> or the frame bearing the END_STREAM flag, it | |
might send frames of these types. Endpoints MUST ignore | |
<x:ref>WINDOW_UPDATE</x:ref> or <x:ref>RST_STREAM</x:ref> frames received in this | |
state, though endpoints MAY choose to treat frames that arrive a significant time | |
after sending END_STREAM as a <xref target="ConnectionErrorHandler">connection | |
error</xref> of type <x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
<x:ref>PRIORITY</x:ref> frames can be sent on closed streams to prioritize streams | |
that are dependent on the closed stream. Endpoints SHOULD process | |
<x:ref>PRIORITY</x:ref> frame, though they can be ignored if the stream has been | |
removed from the dependency tree (see <xref target="priority-gc"/>). | |
</t> | |
<t> | |
If this state is reached as a result of sending a <x:ref>RST_STREAM</x:ref> frame, | |
the peer that receives the <x:ref>RST_STREAM</x:ref> might have already sent - or | |
enqueued for sending - frames on the stream that cannot be withdrawn. An endpoint | |
MUST ignore frames that it receives on closed streams after it has sent a | |
<x:ref>RST_STREAM</x:ref> frame. An endpoint MAY choose to limit the period over | |
which it ignores frames and treat frames that arrive after this time as being in | |
error. | |
</t> | |
<t> | |
Flow controlled frames (i.e., <x:ref>DATA</x:ref>) received after sending | |
<x:ref>RST_STREAM</x:ref> are counted toward the connection flow control window. | |
Even though these frames might be ignored, because they are sent before the sender | |
receives the <x:ref>RST_STREAM</x:ref>, the sender will consider the frames to count | |
against the flow control window. | |
</t> | |
<t> | |
An endpoint might receive a <x:ref>PUSH_PROMISE</x:ref> frame after it sends | |
<x:ref>RST_STREAM</x:ref>. <x:ref>PUSH_PROMISE</x:ref> causes a stream to become | |
"reserved" even if the associated stream has been reset. Therefore, a | |
<x:ref>RST_STREAM</x:ref> is needed to close an unwanted promised stream. | |
</t> | |
</x:lt> | |
</list> | |
</t> | |
<t> | |
In the absence of more specific guidance elsewhere in this document, implementations | |
SHOULD treat the receipt of a frame that is not expressly permitted in the description of | |
a state as a <xref target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. Frame of unknown types are ignored. | |
</t> | |
<t> | |
An example of the state transitions for an HTTP request/response exchange can be found in | |
<xref target="HttpSequence"/>. An example of the state transitions for server push can be | |
found in <xref target="PushRequests"/> and <xref target="PushResponses"/>. | |
</t> | |
<section anchor="StreamIdentifiers" title="Stream Identifiers"> | |
<t> | |
Streams are identified with an unsigned 31-bit integer. Streams initiated by a client | |
MUST use odd-numbered stream identifiers; those initiated by the server MUST use | |
even-numbered stream identifiers. A stream identifier of zero (0x0) is used for | |
connection control messages; the stream identifier zero cannot be used to establish a | |
new stream. | |
</t> | |
<t> | |
HTTP/1.1 requests that are upgraded to HTTP/2 (see <xref target="discover-http"/>) are | |
responded to with a stream identifier of one (0x1). After the upgrade | |
completes, stream 0x1 is "half closed (local)" to the client. Therefore, stream 0x1 | |
cannot be selected as a new stream identifier by a client that upgrades from HTTP/1.1. | |
</t> | |
<t> | |
The identifier of a newly established stream MUST be numerically greater than all | |
streams that the initiating endpoint has opened or reserved. This governs streams that | |
are opened using a <x:ref>HEADERS</x:ref> frame and streams that are reserved using | |
<x:ref>PUSH_PROMISE</x:ref>. An endpoint that receives an unexpected stream identifier | |
MUST respond with a <xref target="ConnectionErrorHandler">connection error</xref> of | |
type <x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
The first use of a new stream identifier implicitly closes all streams in the "idle" | |
state that might have been initiated by that peer with a lower-valued stream identifier. | |
For example, if a client sends a <x:ref>HEADERS</x:ref> frame on stream 7 without ever | |
sending a frame on stream 5, then stream 5 transitions to the "closed" state when the | |
first frame for stream 7 is sent or received. | |
</t> | |
<t> | |
Stream identifiers cannot be reused. Long-lived connections can result in an endpoint | |
exhausting the available range of stream identifiers. A client that is unable to | |
establish a new stream identifier can establish a new connection for new streams. A | |
server that is unable to establish a new stream identifier can send a | |
<x:ref>GOAWAY</x:ref> frame so that the client is forced to open a new connection for | |
new streams. | |
</t> | |
</section> | |
<section title="Stream Concurrency"> | |
<t> | |
A peer can limit the number of concurrently active streams using the | |
<x:ref>SETTINGS_MAX_CONCURRENT_STREAMS</x:ref> parameter (see <xref | |
target="SettingValues"/>) within a <x:ref>SETTINGS</x:ref> frame. The maximum concurrent | |
streams setting is specific to each endpoint and applies only to the peer that receives | |
the setting. That is, clients specify the maximum number of concurrent streams the | |
server can initiate, and servers specify the maximum number of concurrent streams the | |
client can initiate. | |
</t> | |
<t> | |
Streams that are in the "open" state, or either of the "half closed" states count toward | |
the maximum number of streams that an endpoint is permitted to open. Streams in any of | |
these three states count toward the limit advertised in the | |
<x:ref>SETTINGS_MAX_CONCURRENT_STREAMS</x:ref> setting. Streams in either of the | |
"reserved" states do not count toward the stream limit. | |
</t> | |
<t> | |
Endpoints MUST NOT exceed the limit set by their peer. An endpoint that receives a | |
<x:ref>HEADERS</x:ref> frame that causes their advertised concurrent stream limit to be | |
exceeded MUST treat this as a <xref target="StreamErrorHandler">stream error</xref>. An | |
endpoint that wishes to reduce the value of | |
<x:ref>SETTINGS_MAX_CONCURRENT_STREAMS</x:ref> to a value that is below the current | |
number of open streams can either close streams that exceed the new value or allow | |
streams to complete. | |
</t> | |
</section> | |
</section> | |
<section anchor="FlowControl" title="Flow Control"> | |
<t> | |
Using streams for multiplexing introduces contention over use of the TCP connection, | |
resulting in blocked streams. A flow control scheme ensures that streams on the same | |
connection do not destructively interfere with each other. Flow control is used for both | |
individual streams and for the connection as a whole. | |
</t> | |
<t> | |
HTTP/2 provides for flow control through use of the <xref | |
target="WINDOW_UPDATE">WINDOW_UPDATE frame</xref>. | |
</t> | |
<section anchor="fc-principles" title="Flow Control Principles"> | |
<t> | |
HTTP/2 stream flow control aims to allow a variety of flow control algorithms to be | |
used without requiring protocol changes. Flow control in HTTP/2 has the following | |
characteristics: | |
<list style="numbers"> | |
<t> | |
Flow control is specific to a connection; i.e., it is "hop-by-hop", not | |
"end-to-end". | |
</t> | |
<t> | |
Flow control is based on window update frames. Receivers advertise how many octets | |
they are prepared to receive on a stream and for the entire connection. This is a | |
credit-based scheme. | |
</t> | |
<t> | |
Flow control is directional with overall control provided by the receiver. A | |
receiver MAY choose to set any window size that it desires for each stream and for | |
the entire connection. A sender MUST respect flow control limits imposed by a | |
receiver. Clients, servers and intermediaries all independently advertise their | |
flow control window as a receiver and abide by the flow control limits set by | |
their peer when sending. | |
</t> | |
<t> | |
The initial value for the flow control window is 65,535 octets for both new streams | |
and the overall connection. | |
</t> | |
<t> | |
The frame type determines whether flow control applies to a frame. Of the frames | |
specified in this document, only <x:ref>DATA</x:ref> frames are subject to flow | |
control; all other frame types do not consume space in the advertised flow control | |
window. This ensures that important control frames are not blocked by flow control. | |
</t> | |
<t> | |
Flow control cannot be disabled. | |
</t> | |
<t> | |
HTTP/2 defines only the format and semantics of the <x:ref>WINDOW_UPDATE</x:ref> | |
frame (<xref target="WINDOW_UPDATE"/>). This document does not stipulate how a | |
receiver decides when to send this frame or the value that it sends, nor does it | |
specify how a sender chooses to send packets. Implementations are able to select | |
any algorithm that suits their needs. | |
</t> | |
</list> | |
</t> | |
<t> | |
Implementations are also responsible for managing how requests and responses are sent | |
based on priority; choosing how to avoid head of line blocking for requests; and | |
managing the creation of new streams. Algorithm choices for these could interact with | |
any flow control algorithm. | |
</t> | |
</section> | |
<section anchor="DisableFlowControl" title="Appropriate Use of Flow Control"> | |
<t> | |
Flow control is defined to protect endpoints that are operating under resource | |
constraints. For example, a proxy needs to share memory between many connections, and | |
also might have a slow upstream connection and a fast downstream one. Flow control | |
addresses cases where the receiver is unable process data on one stream, yet wants to | |
continue to process other streams in the same connection. | |
</t> | |
<t> | |
Deployments that do not require this capability can advertise a flow control window of | |
the maximum size, incrementing the available space when new data is received. This | |
effectively disables flow control for that receiver. Conversely, a sender is always | |
subject to the flow control window advertised by the receiver. | |
</t> | |
<t> | |
Deployments with constrained resources (for example, memory) can employ flow control to | |
limit the amount of memory a peer can consume. Note, however, that this can lead to | |
suboptimal use of available network resources if flow control is enabled without | |
knowledge of the bandwidth-delay product (see <xref target="RFC1323"/>). | |
</t> | |
<t> | |
Even with full awareness of the current bandwidth-delay product, implementation of flow | |
control can be difficult. When using flow control, the receiver MUST read from the TCP | |
receive buffer in a timely fashion. Failure to do so could lead to a deadlock when | |
critical frames, such as <x:ref>WINDOW_UPDATE</x:ref>, are not read and acted upon. | |
</t> | |
</section> | |
</section> | |
<section anchor="StreamPriority" title="Stream priority"> | |
<t> | |
A client can assign a priority for a new stream by including prioritization information in | |
the <xref target="HEADERS">HEADERS frame</xref> that opens the stream. For an existing | |
stream, the <xref target="PRIORITY">PRIORITY frame</xref> can be used to change the | |
priority. | |
</t> | |
<t> | |
The purpose of prioritization is to allow an endpoint to express how it would prefer its | |
peer allocate resources when managing concurrent streams. Most importantly, priority can | |
be used to select streams for transmitting frames when there is limited capacity for | |
sending. | |
</t> | |
<t> | |
Streams can be prioritized by marking them as dependent on the completion of other streams | |
(<xref target="pri-depend"/>). Each dependency is assigned a relative weight, a number | |
that is used to determine the relative proportion of available resources that are assigned | |
to streams dependent on the same stream. | |
</t> | |
<!-- | |
Note that stream dependencies have not yet been validated in practice. The theory | |
might be fairly sound, but there are no implementations currently sending these. If it | |
turns out that they are not useful, or actively harmful, implementations will be requested | |
to avoid creating stream dependencies. | |
--> | |
<t> | |
Explicitly setting the priority for a stream is input to a prioritization process. It | |
does not guarantee any particular processing or transmission order for the stream relative | |
to any other stream. An endpoint cannot force a peer to process concurrent streams in a | |
particular order using priority. Expressing priority is therefore only ever a suggestion. | |
</t> | |
<t> | |
Providing prioritization information is optional, so default values are used if no | |
explicit indicator is provided (<xref target="pri-default"/>). | |
</t> | |
<section title="Stream Dependencies" anchor="pri-depend"> | |
<t> | |
Each stream can be given an explicit dependency on another stream. Including a | |
dependency expresses a preference to allocate resources to the identified stream rather | |
than to the dependent stream. | |
</t> | |
<t> | |
A stream that is not dependent on any other stream is given a stream dependency of 0x0. | |
In other words, the non-existent stream 0 forms the root of the tree. | |
</t> | |
<t> | |
A stream that depends on another stream is a dependent stream. The stream upon which a | |
stream is dependent is a parent stream. A dependency on a stream that is not currently | |
in the tree - such as a stream in the "idle" state - results in that stream being given | |
a <xref target="pri-default">default priority</xref>. | |
</t> | |
<t> | |
When assigning a dependency on another stream, the stream is added as a new dependency | |
of the parent stream. Dependent streams that share the same parent are not ordered with | |
respect to each other. For example, if streams B and C are dependent on stream A, and | |
if stream D is created with a dependency on stream A, this results in a dependency order | |
of A followed by B, C, and D in any order. | |
</t> | |
<figure title="Example of Default Dependency Creation"> | |
<artwork type="inline"><![CDATA[ | |
A A | |
/ \ ==> /|\ | |
B C B D C | |
]]></artwork> | |
</figure> | |
<t> | |
An exclusive flag allows for the insertion of a new level of dependencies. The | |
exclusive flag causes the stream to become the sole dependency of its parent stream, | |
causing other dependencies to become dependent on the exclusive stream. In the | |
previous example, if stream D is created with an exclusive dependency on stream A, this | |
results in D becoming the dependency parent of B and C. | |
</t> | |
<figure title="Example of Exclusive Dependency Creation"> | |
<artwork type="inline"><![CDATA[ | |
A | |
A | | |
/ \ ==> D | |
B C / \ | |
B C | |
]]></artwork> | |
</figure> | |
<t> | |
Inside the dependency tree, a dependent stream SHOULD only be allocated resources if all | |
of the streams that it depends on (the chain of parent streams up to 0x0) are either | |
closed, or it is not possible to make progress on them. | |
</t> | |
<t> | |
A stream cannot depend on itself. An endpoint MUST treat this as a <xref | |
target="StreamErrorHandler">stream error</xref> of type <x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
</section> | |
<section title="Dependency Weighting"> | |
<t> | |
All dependent streams are allocated an integer weight between 1 and 256 (inclusive). | |
</t> | |
<t> | |
Streams with the same parent SHOULD be allocated resources proportionally based on their | |
weight. Thus, if stream B depends on stream A with weight 4, and C depends on stream A | |
with weight 12, and if no progress can be made on A, stream B ideally receives one third | |
of the resources allocated to stream C. | |
</t> | |
</section> | |
<section anchor="reprioritize" title="Reprioritization"> | |
<t> | |
Stream priorities are changed using the <x:ref>PRIORITY</x:ref> frame. Setting a | |
dependency causes a stream to become dependent on the identified parent stream. | |
</t> | |
<t> | |
Dependent streams move with their parent stream if the parent is reprioritized. Setting | |
a dependency with the exclusive flag for a reprioritized stream moves all the | |
dependencies of the new parent stream to become dependent on the reprioritized stream. | |
</t> | |
<t> | |
If a stream is made dependent on one of its own dependencies, the formerly dependent | |
stream is first moved to be dependent on the reprioritized stream's previous parent. | |
The moved dependency retains its weight. | |
</t> | |
<figure title="Example of Dependency Reordering"> | |
<preamble> | |
For example, consider an original dependency tree where B and C depend on A, D and E | |
depend on C, and F depends on D. If A is made dependent on D, then D takes the place | |
of A. All other dependency relationships stay the same, except for F, which becomes | |
dependent on A if the reprioritization is exclusive. | |
</preamble> | |
<artwork type="inline"><![CDATA[ | |
? ? ? ? | |
| / \ | | | |
A D A D D | |
/ \ / / \ / \ | | |
B C ==> F B C ==> F A OR A | |
/ \ | / \ /|\ | |
D E E B C B C F | |
| | | | |
F E E | |
(intermediate) (non-exclusive) (exclusive) | |
]]></artwork> | |
</figure> | |
</section> | |
<section anchor="priority-gc" title="Prioritization State Management"> | |
<t> | |
When a stream is removed from the dependency tree, its dependencies can be moved to | |
become dependent on the parent of the closed stream. The weights of new dependencies | |
are recalculated by distributing the weight of the dependency of the closed stream | |
proportionally based on the weights of its dependencies. | |
</t> | |
<t> | |
Streams that are removed from the dependency tree cause some prioritization information | |
to be lost. Resources are shared between streams with the same parent stream, which | |
means that if a stream in that set closes or becomes blocked, any spare capacity | |
allocated to a stream is distributed to the immediate neighbors of the stream. However, | |
if the common dependency is removed from the tree, those streams share resources with | |
streams at the next highest level. | |
</t> | |
<t> | |
For example, assume streams A and B share a parent, and streams C and D both depend on | |
stream A. Prior to the removal of stream A, if streams A and D are unable to proceed, | |
then stream C receives all the resources dedicated to stream A. If stream A is removed | |
from the tree, the weight of stream A is divided between streams C and D. If stream D | |
is still unable to proceed, this results in stream C receiving a reduced proportion of | |
resources. For equal starting weights, C receives one third, rather than one half, of | |
available resources. | |
</t> | |
<t> | |
It is possible for a stream to become closed while prioritization information that | |
creates a dependency on that stream is in transit. If a stream identified in a | |
dependency has no associated priority information, then the dependent stream is instead | |
assigned a <xref target="pri-default">default priority</xref>. This potentially creates | |
suboptimal prioritization, since the stream could be given a priority that is different | |
to what is intended. | |
</t> | |
<t> | |
To avoid these problems, an endpoint SHOULD retain stream prioritization state for a | |
period after streams become closed. The longer state is retained, the lower the chance | |
that streams are assigned incorrect or default priority values. | |
</t> | |
<t> | |
This could create a large state burden for an endpoint, so this state MAY be limited. | |
An endpoint MAY apply a fixed upper limit on the number of closed streams for which | |
prioritization state is tracked to limit state exposure. The amount of additional state | |
an endpoint maintains could be dependent on load; under high load, prioritization state | |
can be discarded to limit resource commitments. In extreme cases, an endpoint could | |
even discard prioritization state for active or reserved streams. If a fixed limit is | |
applied, endpoints SHOULD maintain state for at least as many streams as allowed by | |
their setting for <x:ref>SETTINGS_MAX_CONCURRENT_STREAMS</x:ref>. | |
</t> | |
<t> | |
An endpoint receiving a <x:ref>PRIORITY</x:ref> frame that changes the priority of a | |
closed stream SHOULD alter the dependencies of the streams that depend on it, if it has | |
retained enough state to do so. | |
</t> | |
</section> | |
<section title="Default Priorities" anchor="pri-default"> | |
<t> | |
Providing priority information is optional. Streams are assigned a non-exclusive | |
dependency on stream 0x0 by default. <xref target="PushResources">Pushed streams</xref> | |
initially depend on their associated stream. In both cases, streams are assigned a | |
default weight of 16. | |
</t> | |
</section> | |
</section> | |
<section title="Error Handling"> | |
<t> | |
HTTP/2 framing permits two classes of error: | |
<list style="symbols"> | |
<t> | |
An error condition that renders the entire connection unusable is a connection error. | |
</t> | |
<t> | |
An error in an individual stream is a stream error. | |
</t> | |
</list> | |
</t> | |
<t> | |
A list of error codes is included in <xref target="ErrorCodes"/>. | |
</t> | |
<section anchor="ConnectionErrorHandler" title="Connection Error Handling"> | |
<t> | |
A connection error is any error which prevents further processing of the framing layer, | |
or which corrupts any connection state. | |
</t> | |
<t> | |
An endpoint that encounters a connection error SHOULD first send a <x:ref>GOAWAY</x:ref> | |
frame (<xref target="GOAWAY"/>) with the stream identifier of the last stream that it | |
successfully received from its peer. The <x:ref>GOAWAY</x:ref> frame includes an error | |
code that indicates why the connection is terminating. After sending the | |
<x:ref>GOAWAY</x:ref> frame, the endpoint MUST close the TCP connection. | |
</t> | |
<t> | |
It is possible that the <x:ref>GOAWAY</x:ref> will not be reliably received by the | |
receiving endpoint (see <xref target="RFC7230" x:fmt="," | |
x:rel="#persistent.tear-down"/>). In the event of a connection error, | |
<x:ref>GOAWAY</x:ref> only provides a best effort attempt to communicate with the peer | |
about why the connection is being terminated. | |
</t> | |
<t> | |
An endpoint can end a connection at any time. In particular, an endpoint MAY choose to | |
treat a stream error as a connection error. Endpoints SHOULD send a | |
<x:ref>GOAWAY</x:ref> frame when ending a connection, providing that circumstances | |
permit it. | |
</t> | |
</section> | |
<section anchor="StreamErrorHandler" title="Stream Error Handling"> | |
<t> | |
A stream error is an error related to a specific stream that does not affect processing | |
of other streams. | |
</t> | |
<t> | |
An endpoint that detects a stream error sends a <x:ref>RST_STREAM</x:ref> frame (<xref | |
target="RST_STREAM"/>) that contains the stream identifier of the stream where the error | |
occurred. The <x:ref>RST_STREAM</x:ref> frame includes an error code that indicates the | |
type of error. | |
</t> | |
<t> | |
A <x:ref>RST_STREAM</x:ref> is the last frame that an endpoint can send on a stream. | |
The peer that sends the <x:ref>RST_STREAM</x:ref> frame MUST be prepared to receive any | |
frames that were sent or enqueued for sending by the remote peer. These frames can be | |
ignored, except where they modify connection state (such as the state maintained for | |
<xref target="HeaderBlock">header compression</xref>, or flow control). | |
</t> | |
<t> | |
Normally, an endpoint SHOULD NOT send more than one <x:ref>RST_STREAM</x:ref> frame for | |
any stream. However, an endpoint MAY send additional <x:ref>RST_STREAM</x:ref> frames if | |
it receives frames on a closed stream after more than a round-trip time. This behavior | |
is permitted to deal with misbehaving implementations. | |
</t> | |
<t> | |
An endpoint MUST NOT send a <x:ref>RST_STREAM</x:ref> in response to an | |
<x:ref>RST_STREAM</x:ref> frame, to avoid looping. | |
</t> | |
</section> | |
<section title="Connection Termination"> | |
<t> | |
If the TCP connection is closed or reset while streams remain in open or half closed | |
states, then the endpoint MUST assume that those streams were abnormally interrupted and | |
could be incomplete. | |
</t> | |
</section> | |
</section> | |
<section anchor="extensibility" title="Extending HTTP/2"> | |
<t> | |
HTTP/2 permits extension of the protocol. Protocol extensions can be used to provide | |
additional services or alter any aspect of the protocol, within the limitations described | |
in this section. Extensions are effective only within the scope of a single HTTP/2 | |
connection. | |
</t> | |
<t> | |
Extensions are permitted to use new <xref target="FrameHeader">frame types</xref>, new | |
<xref target="SettingValues">settings</xref>, or new <xref target="ErrorCodes">error | |
codes</xref>. Registries are established for managing these extension points: <xref | |
target="iana-frames">frame types</xref>, <xref target="iana-settings">settings</xref> and | |
<xref target="iana-errors">error codes</xref>. | |
</t> | |
<t> | |
Implementations MUST ignore unknown or unsupported values in all extensible protocol | |
elements. Implementations MUST discard frames that have unknown or unsupported types. | |
This means that any of these extension points can be safely used by extensions without | |
prior arrangement or negotiation. However, extension frames that appear in the middle of | |
a <xref target="HeaderBlock">header block</xref> are not permitted; these MUST be treated | |
as a <xref target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
However, extensions that could change the semantics of existing protocol components MUST | |
be negotiated before being used. For example, an extension that changes the layout of the | |
<x:ref>HEADERS</x:ref> frame cannot be used until the peer has given a positive signal | |
that this is acceptable. In this case, it could also be necessary to coordinate when the | |
revised layout comes into effect. Note that treating any frame other than | |
<x:ref>DATA</x:ref> frames as flow controlled is such a change in semantics, and can only | |
be done through negotiation. | |
</t> | |
<t> | |
This document doesn't mandate a specific method for negotiating the use of an extension, | |
but notes that a <xref target="SettingValues">setting</xref> could be used for that | |
purpose. If both peers set a value that indicates willingness to use the extension, then | |
the extension can be used. If a setting is used for extension negotiation, the initial | |
value MUST be defined so that the extension is initially disabled. | |
</t> | |
</section> | |
</section> | |
<section anchor="FrameTypes" title="Frame Definitions"> | |
<t> | |
This specification defines a number of frame types, each identified by a unique 8-bit type | |
code. Each frame type serves a distinct purpose either in the establishment and management | |
of the connection as a whole, or of individual streams. | |
</t> | |
<t> | |
The transmission of specific frame types can alter the state of a connection. If endpoints | |
fail to maintain a synchronized view of the connection state, successful communication | |
within the connection will no longer be possible. Therefore, it is important that endpoints | |
have a shared comprehension of how the state is affected by the use any given frame. | |
</t> | |
<section anchor="DATA" title="DATA"> | |
<t> | |
DATA frames (type=0x0) convey arbitrary, variable-length sequences of octets associated | |
with a stream. One or more DATA frames are used, for instance, to carry HTTP request or | |
response payloads. | |
</t> | |
<t> | |
DATA frames MAY also contain arbitrary padding. Padding can be added to DATA frames to | |
obscure the size of messages. | |
</t> | |
<figure title="DATA Frame Payload"> | |
<artwork type="inline"><![CDATA[ | |
0 1 2 3 | |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
|Pad Length? (8)| | |
+---------------+-----------------------------------------------+ | |
| Data (*) ... | |
+---------------------------------------------------------------+ | |
| Padding (*) ... | |
+---------------------------------------------------------------+ | |
]]></artwork> | |
</figure> | |
<t> | |
The DATA frame contains the following fields: | |
<list style="hanging"> | |
<t hangText="Pad Length:"> | |
An 8-bit field containing the length of the frame padding in units of octets. This | |
field is optional and is only present if the PADDED flag is set. | |
</t> | |
<t hangText="Data:"> | |
Application data. The amount of data is the remainder of the frame payload after | |
subtracting the length of the other fields that are present. | |
</t> | |
<t hangText="Padding:"> | |
Padding octets that contain no application semantic value. Padding octets MUST be set | |
to zero when sending and ignored when receiving. | |
</t> | |
</list> | |
</t> | |
<t> | |
The DATA frame defines the following flags: | |
<list style="hanging"> | |
<t hangText="END_STREAM (0x1):"> | |
Bit 1 being set indicates that this frame is the last that the endpoint will send for | |
the identified stream. Setting this flag causes the stream to enter one of <xref | |
target="StreamStates">the "half closed" states or the "closed" state</xref>. | |
</t> | |
<t hangText="PADDED (0x8):"> | |
Bit 4 being set indicates that the Pad Length field and any padding that it describes | |
is present. | |
</t> | |
</list> | |
</t> | |
<t> | |
DATA frames MUST be associated with a stream. If a DATA frame is received whose stream | |
identifier field is 0x0, the recipient MUST respond with a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
DATA frames are subject to flow control and can only be sent when a stream is in the | |
"open" or "half closed (remote)" states. The entire DATA frame payload is included in flow | |
control, including Pad Length and Padding fields if present. If a DATA frame is received | |
whose stream is not in "open" or "half closed (local)" state, the recipient MUST respond | |
with a <xref target="StreamErrorHandler">stream error</xref> of type | |
<x:ref>STREAM_CLOSED</x:ref>. | |
</t> | |
<t> | |
The total number of padding octets is determined by the value of the Pad Length field. If | |
the length of the padding is greater than the length of the frame payload, the recipient | |
MUST treat this as a <xref target="ConnectionErrorHandler">connection error</xref> of | |
type <x:ref>PROTOCOL_ERROR</x:ref>. | |
<list style="hanging"> | |
<t hangText="Note:"> | |
A frame can be increased in size by one octet by including a Pad Length field with a | |
value of zero. | |
</t> | |
</list> | |
</t> | |
<t> | |
Padding is a security feature; see <xref target="padding"/>. | |
</t> | |
</section> | |
<section anchor="HEADERS" title="HEADERS"> | |
<t> | |
The HEADERS frame (type=0x1) is used to <xref target="StreamStates">open a stream</xref>, | |
and additionally carries a header block fragment. HEADERS frames can be sent on a stream | |
in the "open" or "half closed (remote)" states. | |
</t> | |
<figure title="HEADERS Frame Payload"> | |
<artwork type="inline"><![CDATA[ | |
0 1 2 3 | |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
|Pad Length? (8)| | |
+-+-------------+-----------------------------------------------+ | |
|E| Stream Dependency? (31) | | |
+-+-------------+-----------------------------------------------+ | |
| Weight? (8) | | |
+-+-------------+-----------------------------------------------+ | |
| Header Block Fragment (*) ... | |
+---------------------------------------------------------------+ | |
| Padding (*) ... | |
+---------------------------------------------------------------+ | |
]]></artwork> | |
</figure> | |
<t> | |
The HEADERS frame payload has the following fields: | |
<list style="hanging"> | |
<t hangText="Pad Length:"> | |
An 8-bit field containing the length of the frame padding in units of octets. This | |
field is only present if the PADDED flag is set. | |
</t> | |
<t hangText="E:"> | |
A single bit flag indicates that the stream dependency is exclusive, see <xref | |
target="StreamPriority"/>. This field is only present if the PRIORITY flag is set. | |
</t> | |
<t hangText="Stream Dependency:"> | |
A 31-bit stream identifier for the stream that this stream depends on, see <xref | |
target="StreamPriority"/>. This field is only present if the PRIORITY flag is set. | |
</t> | |
<t hangText="Weight:"> | |
An 8-bit weight for the stream, see <xref target="StreamPriority"/>. Add one to the | |
value to obtain a weight between 1 and 256. This field is only present if the | |
PRIORITY flag is set. | |
</t> | |
<t hangText="Header Block Fragment:"> | |
A <xref target="HeaderBlock">header block fragment</xref>. | |
</t> | |
<t hangText="Padding:"> | |
Padding octets that contain no application semantic value. Padding octets MUST be set | |
to zero when sending and ignored when receiving. | |
</t> | |
</list> | |
</t> | |
<t> | |
The HEADERS frame defines the following flags: | |
<list style="hanging"> | |
<x:lt hangText="END_STREAM (0x1):"> | |
<t> | |
Bit 1 being set indicates that the <xref target="HeaderBlock">header block</xref> is | |
the last that the endpoint will send for the identified stream. Setting this flag | |
causes the stream to enter one of <xref target="StreamStates">"half closed" | |
states</xref>. | |
</t> | |
<t> | |
A HEADERS frame carries the END_STREAM flag that signals the end of a stream. | |
However, a HEADERS frame with the END_STREAM flag set can be followed by | |
<x:ref>CONTINUATION</x:ref> frames on the same stream. Logically, the | |
<x:ref>CONTINUATION</x:ref> frames are part of the HEADERS frame. | |
</t> | |
</x:lt> | |
<x:lt hangText="END_HEADERS (0x4):"> | |
<t> | |
Bit 3 being set indicates that this frame contains an entire <xref | |
target="HeaderBlock">header block</xref> and is not followed by any | |
<x:ref>CONTINUATION</x:ref> frames. | |
</t> | |
<t> | |
A HEADERS frame without the END_HEADERS flag set MUST be followed by a | |
<x:ref>CONTINUATION</x:ref> frame for the same stream. A receiver MUST treat the | |
receipt of any other type of frame or a frame on a different stream as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
</x:lt> | |
<x:lt hangText="PADDED (0x8):"> | |
<t> | |
Bit 4 being set indicates that the Pad Length field and any padding that it | |
describes is present. | |
</t> | |
</x:lt> | |
<x:lt hangText="PRIORITY (0x20):"> | |
<t> | |
Bit 6 being set indicates that the Exclusive Flag (E), Stream Dependency, and Weight | |
fields are present; see <xref target="StreamPriority"/>. | |
</t> | |
</x:lt> | |
</list> | |
</t> | |
<t> | |
The payload of a HEADERS frame contains a <xref target="HeaderBlock">header block | |
fragment</xref>. A header block that does not fit within a HEADERS frame is continued in | |
a <xref target="CONTINUATION">CONTINUATION frame</xref>. | |
</t> | |
<t> | |
HEADERS frames MUST be associated with a stream. If a HEADERS frame is received whose | |
stream identifier field is 0x0, the recipient MUST respond with a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
The HEADERS frame changes the connection state as described in <xref | |
target="HeaderBlock"/>. | |
</t> | |
<t> | |
The HEADERS frame includes optional padding. Padding fields and flags are identical to | |
those defined for <xref target="DATA">DATA frames</xref>. | |
</t> | |
<t> | |
Prioritization information in a HEADERS frame is logically equivalent to a separate | |
<x:ref>PRIORITY</x:ref> frame, but inclusion in HEADERS avoids the potential for churn in | |
stream prioritization when new streams are created. Priorization fields in HEADERS frames | |
subsequent to the first on a stream <xref target="reprioritize">reprioritize the | |
stream</xref>. | |
</t> | |
</section> | |
<section anchor="PRIORITY" title="PRIORITY"> | |
<t> | |
The PRIORITY frame (type=0x2) specifies the <xref target="StreamPriority">sender-advised | |
priority of a stream</xref>. It can be sent at any time for an existing stream, including | |
closed streams. This enables reprioritization of existing streams. | |
</t> | |
<figure title="PRIORITY Frame Payload"> | |
<artwork type="inline"><![CDATA[ | |
0 1 2 3 | |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
|E| Stream Dependency (31) | | |
+-+-------------+-----------------------------------------------+ | |
| Weight (8) | | |
+-+-------------+ | |
]]></artwork> | |
</figure> | |
<t> | |
The payload of a PRIORITY frame contains the following fields: | |
<list style="hanging"> | |
<t hangText="E:"> | |
A single bit flag indicates that the stream dependency is exclusive, see <xref | |
target="StreamPriority"/>. | |
</t> | |
<t hangText="Stream Dependency:"> | |
A 31-bit stream identifier for the stream that this stream depends on, see <xref | |
target="StreamPriority"/>. | |
</t> | |
<t hangText="Weight:"> | |
An 8-bit weight for the identified stream dependency, see <xref | |
target="StreamPriority"/>. Add one to the value to obtain a weight between 1 and 256. | |
</t> | |
</list> | |
</t> | |
<t> | |
The PRIORITY frame does not define any flags. | |
</t> | |
<t> | |
The PRIORITY frame is associated with an existing stream. If a PRIORITY frame is received | |
with a stream identifier of 0x0, the recipient MUST respond with a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
The PRIORITY frame can be sent on a stream in any of the "reserved (remote)", "open", | |
"half closed (local)", "half closed (remote)", or "closed" states, though it cannot be | |
sent between consecutive frames that comprise a single <xref target="HeaderBlock">header | |
block</xref>. Note that this frame could arrive after processing or frame sending has | |
completed, which would cause it to have no effect on the current stream. For a stream | |
that is in the "half closed (remote)" or "closed" - state, this frame can only affect | |
processing of the current stream and not frame transmission. | |
</t> | |
<t> | |
The PRIORITY frame is the only frame that can be sent for a stream in the "closed" state. | |
This allows for the reprioritization of a group of dependent streams by altering the | |
priority of a parent stream, which might be closed. However, a PRIORITY frame sent on a | |
closed stream risks being ignored due to the peer having discarded priority state | |
information for that stream. | |
</t> | |
</section> | |
<section anchor="RST_STREAM" title="RST_STREAM"> | |
<t> | |
The RST_STREAM frame (type=0x3) allows for abnormal termination of a stream. When sent by | |
the initiator of a stream, it indicates that they wish to cancel the stream or that an | |
error condition has occurred. When sent by the receiver of a stream, it indicates that | |
either the receiver is rejecting the stream, requesting that the stream be cancelled, or | |
that an error condition has occurred. | |
</t> | |
<figure title="RST_STREAM Frame Payload"> | |
<artwork type="inline"><![CDATA[ | |
0 1 2 3 | |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| Error Code (32) | | |
+---------------------------------------------------------------+ | |
]]></artwork> | |
</figure> | |
<t> | |
The RST_STREAM frame contains a single unsigned, 32-bit integer identifying the <xref | |
target="ErrorCodes">error code</xref>. The error code indicates why the stream is being | |
terminated. | |
</t> | |
<t> | |
The RST_STREAM frame does not define any flags. | |
</t> | |
<t> | |
The RST_STREAM frame fully terminates the referenced stream and causes it to enter the | |
closed state. After receiving a RST_STREAM on a stream, the receiver MUST NOT send | |
additional frames for that stream, with the exception of <x:ref>PRIORITY</x:ref>. However, | |
after sending the RST_STREAM, the sending endpoint MUST be prepared to receive and process | |
additional frames sent on the stream that might have been sent by the peer prior to the | |
arrival of the RST_STREAM. | |
</t> | |
<t> | |
RST_STREAM frames MUST be associated with a stream. If a RST_STREAM frame is received | |
with a stream identifier of 0x0, the recipient MUST treat this as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
RST_STREAM frames MUST NOT be sent for a stream in the "idle" state. If a RST_STREAM | |
frame identifying an idle stream is received, the recipient MUST treat this as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
</section> | |
<section anchor="SETTINGS" title="SETTINGS"> | |
<t> | |
The SETTINGS frame (type=0x4) conveys configuration parameters that affect how endpoints | |
communicate, such as preferences and constraints on peer behavior. The SETTINGS frame is | |
also used to acknowledge the receipt of those parameters. Individually, a SETTINGS | |
parameter can also be referred to as a "setting". | |
</t> | |
<t> | |
SETTINGS parameters are not negotiated; they describe characteristics of the sending peer, | |
which are used by the receiving peer. Different values for the same parameter can be | |
advertised by each peer. For example, a client might set a high initial flow control | |
window, whereas a server might set a lower value to conserve resources. | |
</t> | |
<t> | |
A SETTINGS frame MUST be sent by both endpoints at the start of a connection, and MAY be | |
sent at any other time by either endpoint over the lifetime of the connection. | |
Implementations MUST support all of the parameters defined by this specification. | |
</t> | |
<t> | |
Each parameter in a SETTINGS frame replaces any existing value for that parameter. | |
Parameters are processed in the order in which they appear, and a receiver of a SETTINGS | |
frame does not need to maintain any state other than the current value of its | |
parameters. Therefore, the value of a SETTINGS parameter is the last value that is seen by | |
a receiver. | |
</t> | |
<t> | |
SETTINGS parameters are acknowledged by the receiving peer. To enable this, the SETTINGS | |
frame defines the following flag: | |
<list style="hanging"> | |
<t hangText="ACK (0x1):"> | |
Bit 1 being set indicates that this frame acknowledges receipt and application of the | |
peer's SETTINGS frame. When this bit is set, the payload of the SETTINGS frame MUST | |
be empty. Receipt of a SETTINGS frame with the ACK flag set and a length field value | |
other than 0 MUST be treated as a <xref target="ConnectionErrorHandler">connection | |
error</xref> of type <x:ref>FRAME_SIZE_ERROR</x:ref>. For more info, see <xref | |
target="SettingsSync">Settings Synchronization</xref>. | |
</t> | |
</list> | |
</t> | |
<t> | |
SETTINGS frames always apply to a connection, never a single stream. The stream | |
identifier for a SETTINGS frame MUST be zero (0x0). If an endpoint receives a SETTINGS | |
frame whose stream identifier field is anything other than 0x0, the endpoint MUST respond | |
with a <xref target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
The SETTINGS frame affects connection state. A badly formed or incomplete SETTINGS frame | |
MUST be treated as a <xref target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<section title="SETTINGS Format" anchor="SettingFormat"> | |
<t> | |
The payload of a SETTINGS frame consists of zero or more parameters, each consisting of | |
an unsigned 16-bit setting identifier and an unsigned 32-bit value. | |
</t> | |
<figure title="Setting Format"> | |
<artwork type="inline"><![CDATA[ | |
0 1 2 3 | |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| Identifier (16) | | |
+-------------------------------+-------------------------------+ | |
| Value (32) | | |
+---------------------------------------------------------------+ | |
]]></artwork> | |
</figure> | |
</section> | |
<section anchor="SettingValues" title="Defined SETTINGS Parameters"> | |
<t> | |
The following parameters are defined: | |
<list style="hanging"> | |
<x:lt hangText="SETTINGS_HEADER_TABLE_SIZE (0x1):" | |
anchor="SETTINGS_HEADER_TABLE_SIZE"> | |
<t> | |
Allows the sender to inform the remote endpoint of the maximum size of the header | |
compression table used to decode header blocks, in octets. The encoder can select | |
any size equal to or less than this value by using signaling specific to the | |
header compression format inside a header block. The initial value is 4,096 | |
octets. | |
</t> | |
</x:lt> | |
<x:lt hangText="SETTINGS_ENABLE_PUSH (0x2):" | |
anchor="SETTINGS_ENABLE_PUSH"> | |
<t> | |
This setting can be use to disable <xref target="PushResources">server | |
push</xref>. An endpoint MUST NOT send a <x:ref>PUSH_PROMISE</x:ref> frame if it | |
receives this parameter set to a value of 0. An endpoint that has both set this | |
parameter to 0 and had it acknowledged MUST treat the receipt of a | |
<x:ref>PUSH_PROMISE</x:ref> frame as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
The initial value is 1, which indicates that server push is permitted. Any value | |
other than 0 or 1 MUST be treated as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
</x:lt> | |
<x:lt hangText="SETTINGS_MAX_CONCURRENT_STREAMS (0x3):" | |
anchor="SETTINGS_MAX_CONCURRENT_STREAMS"> | |
<t> | |
Indicates the maximum number of concurrent streams that the sender will allow. | |
This limit is directional: it applies to the number of streams that the sender | |
permits the receiver to create. Initially there is no limit to this value. It is | |
recommended that this value be no smaller than 100, so as to not unnecessarily | |
limit parallelism. | |
</t> | |
<t> | |
A value of 0 for SETTINGS_MAX_CONCURRENT_STREAMS SHOULD NOT be treated as special | |
by endpoints. A zero value does prevent the creation of new streams, however this | |
can also happen for any limit that is exhausted with active streams. Servers | |
SHOULD only set a zero value for short durations; if a server does not wish to | |
accept requests, closing the connection could be preferable. | |
</t> | |
</x:lt> | |
<x:lt hangText="SETTINGS_INITIAL_WINDOW_SIZE (0x4):" | |
anchor="SETTINGS_INITIAL_WINDOW_SIZE"> | |
<t> | |
Indicates the sender's initial window size (in octets) for stream level flow | |
control. The initial value is 2<x:sup>16</x:sup>-1 (65,535) octets. | |
</t> | |
<t> | |
This setting affects the window size of all streams, including existing streams, | |
see <xref target="InitialWindowSize"/>. | |
</t> | |
<t> | |
Values above the maximum flow control window size of 2<x:sup>31</x:sup>-1 MUST | |
be treated as a <xref target="ConnectionErrorHandler">connection error</xref> of | |
type <x:ref>FLOW_CONTROL_ERROR</x:ref>. | |
</t> | |
</x:lt> | |
<x:lt hangText="SETTINGS_MAX_FRAME_SIZE (0x5):" | |
anchor="SETTINGS_MAX_FRAME_SIZE"> | |
<t> | |
Indicates the size of the largest frame payload that the sender is willing to | |
receive, in octets. | |
</t> | |
<t> | |
The initial value is 2<x:sup>14</x:sup> (16,384) octets. The value advertised by | |
an endpoint MUST be between this initial value and the maximum allowed frame size | |
(2<x:sup>24</x:sup>-1 or 16,777,215 octets), inclusive. Values outside this range | |
MUST be treated as a <xref target="ConnectionErrorHandler">connection error</xref> | |
of type <x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
</x:lt> | |
<x:lt hangText="SETTINGS_MAX_HEADER_LIST_SIZE (0x6):" | |
anchor="SETTINGS_MAX_HEADER_LIST_SIZE"> | |
<t> | |
This advisory setting informs a peer of the maximum size of header list that the | |
sender is prepared to accept, in octets. The value is based on the uncompressed | |
size of header fields, including the length of the name and value in octets plus | |
an overhead of 32 octets for each header field. | |
</t> | |
<t> | |
For any given request, a lower limit than what is advertised MAY be enforced. The | |
initial value of this setting is unlimited. | |
</t> | |
</x:lt> | |
</list> | |
</t> | |
<t> | |
An endpoint that receives a SETTINGS frame with any unknown or unsupported identifier | |
MUST ignore that setting. | |
</t> | |
</section> | |
<section anchor="SettingsSync" title="Settings Synchronization"> | |
<t> | |
Most values in SETTINGS benefit from or require an understanding of when the peer has | |
received and applied the changed parameter values. In order to provide | |
such synchronization timepoints, the recipient of a SETTINGS frame in which the ACK flag | |
is not set MUST apply the updated parameters as soon as possible upon receipt. | |
</t> | |
<t> | |
The values in the SETTINGS frame MUST be processed in the order they appear, with no | |
other frame processing between values. Unsupported parameters MUST be ignored. Once | |
all values have been processed, the recipient MUST immediately emit a SETTINGS frame | |
with the ACK flag set. Upon receiving a SETTINGS frame with the ACK flag set, the sender | |
of the altered parameters can rely on the setting having been applied. | |
</t> | |
<t> | |
If the sender of a SETTINGS frame does not receive an acknowledgement within a | |
reasonable amount of time, it MAY issue a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>SETTINGS_TIMEOUT</x:ref>. | |
</t> | |
</section> | |
</section> | |
<section anchor="PUSH_PROMISE" title="PUSH_PROMISE"> | |
<t> | |
The PUSH_PROMISE frame (type=0x5) is used to notify the peer endpoint in advance of | |
streams the sender intends to initiate. The PUSH_PROMISE frame includes the unsigned | |
31-bit identifier of the stream the endpoint plans to create along with a set of headers | |
that provide additional context for the stream. <xref target="PushResources"/> contains a | |
thorough description of the use of PUSH_PROMISE frames. | |
</t> | |
<figure title="PUSH_PROMISE Payload Format"> | |
<artwork type="inline"><![CDATA[ | |
0 1 2 3 | |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
|Pad Length? (8)| | |
+-+-------------+-----------------------------------------------+ | |
|R| Promised Stream ID (31) | | |
+-+-----------------------------+-------------------------------+ | |
| Header Block Fragment (*) ... | |
+---------------------------------------------------------------+ | |
| Padding (*) ... | |
+---------------------------------------------------------------+ | |
]]></artwork> | |
</figure> | |
<t> | |
The PUSH_PROMISE frame payload has the following fields: | |
<list style="hanging"> | |
<t hangText="Pad Length:"> | |
An 8-bit field containing the length of the frame padding in units of octets. This | |
field is only present if the PADDED flag is set. | |
</t> | |
<t hangText="R:"> | |
A single reserved bit. | |
</t> | |
<t hangText="Promised Stream ID:"> | |
An unsigned 31-bit integer that identifies the stream that is reserved by the | |
PUSH_PROMISE. The promised stream identifier MUST be a valid choice for the next | |
stream sent by the sender (see <xref target="StreamIdentifiers">new stream | |
identifier</xref>). | |
</t> | |
<t hangText="Header Block Fragment:"> | |
A <xref target="HeaderBlock">header block fragment</xref> containing request header | |
fields. | |
</t> | |
<t hangText="Padding:"> | |
Padding octets. | |
</t> | |
</list> | |
</t> | |
<t> | |
The PUSH_PROMISE frame defines the following flags: | |
<list style="hanging"> | |
<x:lt hangText="END_HEADERS (0x4):"> | |
<t> | |
Bit 3 being set indicates that this frame contains an entire <xref | |
target="HeaderBlock">header block</xref> and is not followed by any | |
<x:ref>CONTINUATION</x:ref> frames. | |
</t> | |
<t> | |
A PUSH_PROMISE frame without the END_HEADERS flag set MUST be followed by a | |
CONTINUATION frame for the same stream. A receiver MUST treat the receipt of any | |
other type of frame or a frame on a different stream as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
</x:lt> | |
<x:lt hangText="PADDED (0x8):"> | |
<t> | |
Bit 4 being set indicates that the Pad Length field and any padding that it | |
describes is present. | |
</t> | |
</x:lt> | |
</list> | |
</t> | |
<t> | |
PUSH_PROMISE frames MUST be associated with an existing, peer-initiated stream. The stream | |
identifier of a PUSH_PROMISE frame indicates the stream it is associated with. If the | |
stream identifier field specifies the value 0x0, a recipient MUST respond with a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
Promised streams are not required to be used in the order they are promised. The | |
PUSH_PROMISE only reserves stream identifiers for later use. | |
</t> | |
<t> | |
PUSH_PROMISE MUST NOT be sent if the <x:ref>SETTINGS_ENABLE_PUSH</x:ref> setting of the | |
peer endpoint is set to 0. An endpoint that has set this setting and has received | |
acknowledgement MUST treat the receipt of a PUSH_PROMISE frame as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
Recipients of PUSH_PROMISE frames can choose to reject promised streams by returning a | |
<x:ref>RST_STREAM</x:ref> referencing the promised stream identifier back to the sender of | |
the PUSH_PROMISE. | |
</t> | |
<t> | |
A PUSH_PROMISE frame modifies the connection state in two ways. The inclusion of a <xref | |
target="HeaderBlock">header block</xref> potentially modifies the state maintained for | |
header compression. PUSH_PROMISE also reserves a stream for later use, causing the | |
promised stream to enter the "reserved" state. A sender MUST NOT send a PUSH_PROMISE on a | |
stream unless that stream is either "open" or "half closed (remote)"; the sender MUST | |
ensure that the promised stream is a valid choice for a <xref | |
target="StreamIdentifiers">new stream identifier</xref> (that is, the promised stream MUST | |
be in the "idle" state). | |
</t> | |
<t> | |
Since PUSH_PROMISE reserves a stream, ignoring a PUSH_PROMISE frame causes the stream | |
state to become indeterminate. A receiver MUST treat the receipt of a PUSH_PROMISE on a | |
stream that is neither "open" nor "half closed (local)" as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. However, an endpoint that has sent | |
<x:ref>RST_STREAM</x:ref> on the associated stream MUST handle PUSH_PROMISE frames that | |
might have been created before the <x:ref>RST_STREAM</x:ref> frame is received and | |
processed. | |
</t> | |
<t> | |
A receiver MUST treat the receipt of a PUSH_PROMISE that promises an <xref | |
target="StreamIdentifiers">illegal stream identifier</xref> (that is, an identifier for a | |
stream that is not currently in the "idle" state) as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
The PUSH_PROMISE frame includes optional padding. Padding fields and flags are identical | |
to those defined for <xref target="DATA">DATA frames</xref>. | |
</t> | |
</section> | |
<section anchor="PING" title="PING"> | |
<t> | |
The PING frame (type=0x6) is a mechanism for measuring a minimal round trip time from the | |
sender, as well as determining whether an idle connection is still functional. PING | |
frames can be sent from any endpoint. | |
</t> | |
<figure title="PING Payload Format"> | |
<artwork type="inline"><![CDATA[ | |
0 1 2 3 | |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| | | |
| Opaque Data (64) | | |
| | | |
+---------------------------------------------------------------+ | |
]]></artwork> | |
</figure> | |
<t> | |
In addition to the frame header, PING frames MUST contain 8 octets of data in the payload. | |
A sender can include any value it chooses and use those bytes in any fashion. | |
</t> | |
<t> | |
Receivers of a PING frame that does not include an ACK flag MUST send a PING frame with | |
the ACK flag set in response, with an identical payload. PING responses SHOULD be given | |
higher priority than any other frame. | |
</t> | |
<t> | |
The PING frame defines the following flags: | |
<list style="hanging"> | |
<t hangText="ACK (0x1):"> | |
Bit 1 being set indicates that this PING frame is a PING response. An endpoint MUST | |
set this flag in PING responses. An endpoint MUST NOT respond to PING frames | |
containing this flag. | |
</t> | |
</list> | |
</t> | |
<t> | |
PING frames are not associated with any individual stream. If a PING frame is received | |
with a stream identifier field value other than 0x0, the recipient MUST respond with a | |
<xref target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
Receipt of a PING frame with a length field value other than 8 MUST be treated as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>FRAME_SIZE_ERROR</x:ref>. | |
</t> | |
</section> | |
<section anchor="GOAWAY" title="GOAWAY"> | |
<t> | |
The GOAWAY frame (type=0x7) informs the remote peer to stop creating streams on this | |
connection. GOAWAY can be sent by either the client or the server. Once sent, the sender | |
will ignore frames sent on any new streams with identifiers higher than the included last | |
stream identifier. Receivers of a GOAWAY frame MUST NOT open additional streams on the | |
connection, although a new connection can be established for new streams. | |
</t> | |
<t> | |
The purpose of this frame is to allow an endpoint to gracefully stop accepting new | |
streams, while still finishing processing of previously established streams. This enables | |
administrative actions, like server maintenance. | |
</t> | |
<t> | |
There is an inherent race condition between an endpoint starting new streams and the | |
remote sending a GOAWAY frame. To deal with this case, the GOAWAY contains the stream | |
identifier of the last peer-initiated stream which was or might be processed on the | |
sending endpoint in this connection. For instance, if the server sends a GOAWAY frame, | |
the identified stream is the highest numbered stream initiated by the client. | |
</t> | |
<t> | |
If the receiver of the GOAWAY has sent data on streams with a higher stream identifier | |
than what is indicated in the GOAWAY frame, those streams are not or will not be | |
processed. The receiver of the GOAWAY frame can treat the streams as though they had | |
never been created at all, thereby allowing those streams to be retried later on a new | |
connection. | |
</t> | |
<t> | |
Endpoints SHOULD always send a GOAWAY frame before closing a connection so that the remote | |
can know whether a stream has been partially processed or not. For example, if an HTTP | |
client sends a POST at the same time that a server closes a connection, the client cannot | |
know if the server started to process that POST request if the server does not send a | |
GOAWAY frame to indicate what streams it might have acted on. | |
</t> | |
<t> | |
An endpoint might choose to close a connection without sending GOAWAY for misbehaving | |
peers. | |
</t> | |
<figure title="GOAWAY Payload Format"> | |
<artwork type="inline"><![CDATA[ | |
0 1 2 3 | |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
|R| Last-Stream-ID (31) | | |
+-+-------------------------------------------------------------+ | |
| Error Code (32) | | |
+---------------------------------------------------------------+ | |
| Additional Debug Data (*) | | |
+---------------------------------------------------------------+ | |
]]></artwork> | |
</figure> | |
<t> | |
The GOAWAY frame does not define any flags. | |
</t> | |
<t> | |
The GOAWAY frame applies to the connection, not a specific stream. An endpoint MUST treat | |
a <x:ref>GOAWAY</x:ref> frame with a stream identifier other than 0x0 as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
The last stream identifier in the GOAWAY frame contains the highest numbered stream | |
identifier for which the sender of the GOAWAY frame might have taken some action on, or | |
might yet take action on. All streams up to and including the identified stream might | |
have been processed in some way. The last stream identifier can be set to 0 if no streams | |
were processed. | |
<list style="hanging"> | |
<t hangText="Note:"> | |
In this context, "processed" means that some data from the stream was passed to some | |
higher layer of software that might have taken some action as a result. | |
</t> | |
</list> | |
If a connection terminates without a GOAWAY frame, the last stream identifier is | |
effectively the highest possible stream identifier. | |
</t> | |
<t> | |
On streams with lower or equal numbered identifiers that were not closed completely prior | |
to the connection being closed, re-attempting requests, transactions, or any protocol | |
activity is not possible, with the exception of idempotent actions like HTTP GET, PUT, or | |
DELETE. Any protocol activity that uses higher numbered streams can be safely retried | |
using a new connection. | |
</t> | |
<t> | |
Activity on streams numbered lower or equal to the last stream identifier might still | |
complete successfully. The sender of a GOAWAY frame might gracefully shut down a | |
connection by sending a GOAWAY frame, maintaining the connection in an open state until | |
all in-progress streams complete. | |
</t> | |
<t> | |
An endpoint MAY send multiple GOAWAY frames if circumstances change. For instance, an | |
endpoint that sends GOAWAY with <x:ref>NO_ERROR</x:ref> during graceful shutdown could | |
subsequently encounter an condition that requires immediate termination of the connection. | |
The last stream identifier from the last GOAWAY frame received indicates which streams | |
could have been acted upon. Endpoints MUST NOT increase the value they send in the last | |
stream identifier, since the peers might already have retried unprocessed requests on | |
another connection. | |
</t> | |
<t> | |
A client that is unable to retry requests loses all requests that are in flight when the | |
server closes the connection. This is especially true for intermediaries that might | |
not be serving clients using HTTP/2. A server that is attempting to gracefully shut down | |
a connection SHOULD send an initial GOAWAY frame with the last stream identifier set to | |
2<x:sup>31</x:sup>-1 and a <x:ref>NO_ERROR</x:ref> code. This signals to the client that | |
a shutdown is imminent and that no further requests can be initiated. After waiting at | |
least one round trip time, the server can send another GOAWAY frame with an updated last | |
stream identifier. This ensures that a connection can be cleanly shut down without losing | |
requests. | |
</t> | |
<t> | |
After sending a GOAWAY frame, the sender can discard frames for streams with identifiers | |
higher than the identified last stream. However, any frames that alter connection state | |
cannot be completely ignored. For instance, <x:ref>HEADERS</x:ref>, | |
<x:ref>PUSH_PROMISE</x:ref> and <x:ref>CONTINUATION</x:ref> frames MUST be minimally | |
processed to ensure the state maintained for header compression is consistent (see <xref | |
target="HeaderBlock"/>); similarly DATA frames MUST be counted toward the connection flow | |
control window. Failure to process these frames can cause flow control or header | |
compression state to become unsynchronized. | |
</t> | |
<t> | |
The GOAWAY frame also contains a 32-bit <xref target="ErrorCodes">error code</xref> that | |
contains the reason for closing the connection. | |
</t> | |
<t> | |
Endpoints MAY append opaque data to the payload of any GOAWAY frame. Additional debug | |
data is intended for diagnostic purposes only and carries no semantic value. Debug | |
information could contain security- or privacy-sensitive data. Logged or otherwise | |
persistently stored debug data MUST have adequate safeguards to prevent unauthorized | |
access. | |
</t> | |
</section> | |
<section anchor="WINDOW_UPDATE" title="WINDOW_UPDATE"> | |
<t> | |
The WINDOW_UPDATE frame (type=0x8) is used to implement flow control; see <xref | |
target="FlowControl"/> for an overview. | |
</t> | |
<t> | |
Flow control operates at two levels: on each individual stream and on the entire | |
connection. | |
</t> | |
<t> | |
Both types of flow control are hop-by-hop; that is, only between the two endpoints. | |
Intermediaries do not forward WINDOW_UPDATE frames between dependent connections. | |
However, throttling of data transfer by any receiver can indirectly cause the propagation | |
of flow control information toward the original sender. | |
</t> | |
<t> | |
Flow control only applies to frames that are identified as being subject to flow control. | |
Of the frame types defined in this document, this includes only <x:ref>DATA</x:ref> frames. | |
Frames that are exempt from flow control MUST be accepted and processed, unless the | |
receiver is unable to assign resources to handling the frame. A receiver MAY respond with | |
a <xref target="StreamErrorHandler">stream error</xref> or <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>FLOW_CONTROL_ERROR</x:ref> if it is unable to accept a frame. | |
</t> | |
<figure title="WINDOW_UPDATE Payload Format"> | |
<artwork type="inline"><![CDATA[ | |
0 1 2 3 | |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
|R| Window Size Increment (31) | | |
+-+-------------------------------------------------------------+ | |
]]></artwork> | |
</figure> | |
<t> | |
The payload of a WINDOW_UPDATE frame is one reserved bit, plus an unsigned 31-bit integer | |
indicating the number of octets that the sender can transmit in addition to the existing | |
flow control window. The legal range for the increment to the flow control window is 1 to | |
2<x:sup>31</x:sup>-1 (0x7fffffff) octets. | |
</t> | |
<t> | |
The WINDOW_UPDATE frame does not define any flags. | |
</t> | |
<t> | |
The WINDOW_UPDATE frame can be specific to a stream or to the entire connection. In the | |
former case, the frame's stream identifier indicates the affected stream; in the latter, | |
the value "0" indicates that the entire connection is the subject of the frame. | |
</t> | |
<t> | |
A receiver MUST treat the receipt of a WINDOW_UPDATE frame with an flow control window | |
increment of 0 as a <xref target="StreamErrorHandler">stream error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>; errors on the connection flow control window MUST be | |
treated as a <xref target="ConnectionErrorHandler">connection error</xref>. | |
</t> | |
<t> | |
WINDOW_UPDATE can be sent by a peer that has sent a frame bearing the END_STREAM flag. | |
This means that a receiver could receive a WINDOW_UPDATE frame on a "half closed (remote)" | |
or "closed" stream. A receiver MUST NOT treat this as an error, see <xref | |
target="StreamStates"/>. | |
</t> | |
<t> | |
A receiver that receives a flow controlled frame MUST always account for its contribution | |
against the connection flow control window, unless the receiver treats this as a <xref | |
target="ConnectionErrorHandler">connection error</xref>. This is necessary even if the | |
frame is in error. Since the sender counts the frame toward the flow control window, if | |
the receiver does not, the flow control window at sender and receiver can become | |
different. | |
</t> | |
<section title="The Flow Control Window"> | |
<t> | |
Flow control in HTTP/2 is implemented using a window kept by each sender on every | |
stream. The flow control window is a simple integer value that indicates how many octets | |
of data the sender is permitted to transmit; as such, its size is a measure of the | |
buffering capacity of the receiver. | |
</t> | |
<t> | |
Two flow control windows are applicable: the stream flow control window and the | |
connection flow control window. The sender MUST NOT send a flow controlled frame with a | |
length that exceeds the space available in either of the flow control windows advertised | |
by the receiver. Frames with zero length with the END_STREAM flag set (that is, an | |
empty <x:ref>DATA</x:ref> frame) MAY be sent if there is no available space in either | |
flow control window. | |
</t> | |
<t> | |
For flow control calculations, the 9 octet frame header is not counted. | |
</t> | |
<t> | |
After sending a flow controlled frame, the sender reduces the space available in both | |
windows by the length of the transmitted frame. | |
</t> | |
<t> | |
The receiver of a frame sends a WINDOW_UPDATE frame as it consumes data and frees up | |
space in flow control windows. Separate WINDOW_UPDATE frames are sent for the stream | |
and connection level flow control windows. | |
</t> | |
<t> | |
A sender that receives a WINDOW_UPDATE frame updates the corresponding window by the | |
amount specified in the frame. | |
</t> | |
<t> | |
A sender MUST NOT allow a flow control window to exceed 2<x:sup>31</x:sup>-1 octets. | |
If a sender receives a WINDOW_UPDATE that causes a flow control window to exceed this | |
maximum it MUST terminate either the stream or the connection, as appropriate. For | |
streams, the sender sends a <x:ref>RST_STREAM</x:ref> with the error code of | |
<x:ref>FLOW_CONTROL_ERROR</x:ref> code; for the connection, a <x:ref>GOAWAY</x:ref> | |
frame with a <x:ref>FLOW_CONTROL_ERROR</x:ref> code. | |
</t> | |
<t> | |
Flow controlled frames from the sender and WINDOW_UPDATE frames from the receiver are | |
completely asynchronous with respect to each other. This property allows a receiver to | |
aggressively update the window size kept by the sender to prevent streams from stalling. | |
</t> | |
</section> | |
<section anchor="InitialWindowSize" title="Initial Flow Control Window Size"> | |
<t> | |
When an HTTP/2 connection is first established, new streams are created with an initial | |
flow control window size of 65,535 octets. The connection flow control window is 65,535 | |
octets. Both endpoints can adjust the initial window size for new streams by including | |
a value for <x:ref>SETTINGS_INITIAL_WINDOW_SIZE</x:ref> in the <x:ref>SETTINGS</x:ref> | |
frame that forms part of the connection preface. The connection flow control window can | |
only be changed using WINDOW_UPDATE frames. | |
</t> | |
<t> | |
Prior to receiving a <x:ref>SETTINGS</x:ref> frame that sets a value for | |
<x:ref>SETTINGS_INITIAL_WINDOW_SIZE</x:ref>, an endpoint can only use the default | |
initial window size when sending flow controlled frames. Similarly, the connection flow | |
control window is set to the default initial window size until a WINDOW_UPDATE frame is | |
received. | |
</t> | |
<t> | |
A <x:ref>SETTINGS</x:ref> frame can alter the initial flow control window size for all | |
current streams. When the value of <x:ref>SETTINGS_INITIAL_WINDOW_SIZE</x:ref> changes, | |
a receiver MUST adjust the size of all stream flow control windows that it maintains by | |
the difference between the new value and the old value. | |
</t> | |
<t> | |
A change to <x:ref>SETTINGS_INITIAL_WINDOW_SIZE</x:ref> can cause the available space in | |
a flow control window to become negative. A sender MUST track the negative flow control | |
window, and MUST NOT send new flow controlled frames until it receives WINDOW_UPDATE | |
frames that cause the flow control window to become positive. | |
</t> | |
<t> | |
For example, if the client sends 60KB immediately on connection establishment, and the | |
server sets the initial window size to be 16KB, the client will recalculate the | |
available flow control window to be -44KB on receipt of the <x:ref>SETTINGS</x:ref> | |
frame. The client retains a negative flow control window until WINDOW_UPDATE frames | |
restore the window to being positive, after which the client can resume sending. | |
</t> | |
<t> | |
A <x:ref>SETTINGS</x:ref> frame cannot alter the connection flow control window. | |
</t> | |
<t> | |
An endpoint MUST treat a change to <x:ref>SETTINGS_INITIAL_WINDOW_SIZE</x:ref> that | |
causes any flow control window to exceed the maximum size as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>FLOW_CONTROL_ERROR</x:ref>. | |
</t> | |
</section> | |
<section title="Reducing the Stream Window Size"> | |
<t> | |
A receiver that wishes to use a smaller flow control window than the current size can | |
send a new <x:ref>SETTINGS</x:ref> frame. However, the receiver MUST be prepared to | |
receive data that exceeds this window size, since the sender might send data that | |
exceeds the lower limit prior to processing the <x:ref>SETTINGS</x:ref> frame. | |
</t> | |
<t> | |
After sending a SETTINGS frame that reduces the initial flow control window size, a | |
receiver has two options for handling streams that exceed flow control limits: | |
<list style="numbers"> | |
<t> | |
The receiver can immediately send <x:ref>RST_STREAM</x:ref> with | |
<x:ref>FLOW_CONTROL_ERROR</x:ref> error code for the affected streams. | |
</t> | |
<t> | |
The receiver can accept the streams and tolerate the resulting head of line | |
blocking, sending WINDOW_UPDATE frames as it consumes data. | |
</t> | |
</list> | |
</t> | |
</section> | |
</section> | |
<section anchor="CONTINUATION" title="CONTINUATION"> | |
<t> | |
The CONTINUATION frame (type=0x9) is used to continue a sequence of <xref | |
target="HeaderBlock">header block fragments</xref>. Any number of CONTINUATION frames can | |
be sent on an existing stream, as long as the preceding frame is on the same stream and is | |
a <x:ref>HEADERS</x:ref>, <x:ref>PUSH_PROMISE</x:ref> or CONTINUATION frame without the | |
END_HEADERS flag set. | |
</t> | |
<figure title="CONTINUATION Frame Payload"> | |
<artwork type="inline"><![CDATA[ | |
0 1 2 3 | |
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| Header Block Fragment (*) ... | |
+---------------------------------------------------------------+ | |
]]></artwork> | |
</figure> | |
<t> | |
The CONTINUATION frame payload contains a <xref target="HeaderBlock">header block | |
fragment</xref>. | |
</t> | |
<t> | |
The CONTINUATION frame defines the following flag: | |
<list style="hanging"> | |
<x:lt hangText="END_HEADERS (0x4):"> | |
<t> | |
Bit 3 being set indicates that this frame ends a <xref target="HeaderBlock">header | |
block</xref>. | |
</t> | |
<t> | |
If the END_HEADERS bit is not set, this frame MUST be followed by another | |
CONTINUATION frame. A receiver MUST treat the receipt of any other type of frame or | |
a frame on a different stream as a <xref target="ConnectionErrorHandler">connection | |
error</xref> of type <x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
</x:lt> | |
</list> | |
</t> | |
<t> | |
The CONTINUATION frame changes the connection state as defined in <xref | |
target="HeaderBlock" />. | |
</t> | |
<t> | |
CONTINUATION frames MUST be associated with a stream. If a CONTINUATION frame is received | |
whose stream identifier field is 0x0, the recipient MUST respond with a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type PROTOCOL_ERROR. | |
</t> | |
<t> | |
A CONTINUATION frame MUST be preceded by a <x:ref>HEADERS</x:ref>, | |
<x:ref>PUSH_PROMISE</x:ref> or CONTINUATION frame without the END_HEADERS flag set. A | |
recipient that observes violation of this rule MUST respond with a <xref | |
target="ConnectionErrorHandler"> connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
</section> | |
</section> | |
<section anchor="ErrorCodes" title="Error Codes"> | |
<t> | |
Error codes are 32-bit fields that are used in <x:ref>RST_STREAM</x:ref> and | |
<x:ref>GOAWAY</x:ref> frames to convey the reasons for the stream or connection error. | |
</t> | |
<t> | |
Error codes share a common code space. Some error codes apply only to either streams or the | |
entire connection and have no defined semantics in the other context. | |
</t> | |
<t> | |
The following error codes are defined: | |
<list style="hanging"> | |
<t hangText="NO_ERROR (0x0):" anchor="NO_ERROR"> | |
The associated condition is not as a result of an error. For example, a | |
<x:ref>GOAWAY</x:ref> might include this code to indicate graceful shutdown of a | |
connection. | |
</t> | |
<t hangText="PROTOCOL_ERROR (0x1):" anchor="PROTOCOL_ERROR"> | |
The endpoint detected an unspecific protocol error. This error is for use when a more | |
specific error code is not available. | |
</t> | |
<t hangText="INTERNAL_ERROR (0x2):" anchor="INTERNAL_ERROR"> | |
The endpoint encountered an unexpected internal error. | |
</t> | |
<t hangText="FLOW_CONTROL_ERROR (0x3):" anchor="FLOW_CONTROL_ERROR"> | |
The endpoint detected that its peer violated the flow control protocol. | |
</t> | |
<t hangText="SETTINGS_TIMEOUT (0x4):" anchor="SETTINGS_TIMEOUT"> | |
The endpoint sent a <x:ref>SETTINGS</x:ref> frame, but did not receive a response in a | |
timely manner. See <xref target="SettingsSync">Settings Synchronization</xref>. | |
</t> | |
<t hangText="STREAM_CLOSED (0x5):" anchor="STREAM_CLOSED"> | |
The endpoint received a frame after a stream was half closed. | |
</t> | |
<t hangText="FRAME_SIZE_ERROR (0x6):" anchor="FRAME_SIZE_ERROR"> | |
The endpoint received a frame with an invalid size. | |
</t> | |
<t hangText="REFUSED_STREAM (0x7):" anchor="REFUSED_STREAM"> | |
The endpoint refuses the stream prior to performing any application processing, see | |
<xref target="Reliability"/> for details. | |
</t> | |
<t hangText="CANCEL (0x8):" anchor="CANCEL"> | |
Used by the endpoint to indicate that the stream is no longer needed. | |
</t> | |
<t hangText="COMPRESSION_ERROR (0x9):" anchor="COMPRESSION_ERROR"> | |
The endpoint is unable to maintain the header compression context for the connection. | |
</t> | |
<t hangText="CONNECT_ERROR (0xa):" anchor="CONNECT_ERROR"> | |
The connection established in response to a <xref target="CONNECT">CONNECT | |
request</xref> was reset or abnormally closed. | |
</t> | |
<t hangText="ENHANCE_YOUR_CALM (0xb):" anchor="ENHANCE_YOUR_CALM"> | |
The endpoint detected that its peer is exhibiting a behavior that might be generating | |
excessive load. | |
</t> | |
<t hangText="INADEQUATE_SECURITY (0xc):" anchor="INADEQUATE_SECURITY"> | |
The underlying transport has properties that do not meet minimum security | |
requirements (see <xref target="TLSUsage"/>). | |
</t> | |
</list> | |
</t> | |
<t> | |
Unknown or unsupported error codes MUST NOT trigger any special behavior. These MAY be | |
treated by an implementation as being equivalent to <x:ref>INTERNAL_ERROR</x:ref>. | |
</t> | |
</section> | |
<section anchor="HTTPLayer" title="HTTP Message Exchanges"> | |
<t> | |
HTTP/2 is intended to be as compatible as possible with current uses of HTTP. This means | |
that, from the application perspective, the features of the protocol are largely | |
unchanged. To achieve this, all request and response semantics are preserved, although the | |
syntax of conveying those semantics has changed. | |
</t> | |
<t> | |
Thus, the specification and requirements of HTTP/1.1 Semantics and Content <xref | |
target="RFC7231"/>, Conditional Requests <xref target="RFC7232"/>, Range Requests <xref | |
target="RFC7233"/>, Caching <xref target="RFC7234"/> and Authentication <xref | |
target="RFC7235"/> are applicable to HTTP/2. Selected portions of HTTP/1.1 Message Syntax | |
and Routing <xref target="RFC7230"/>, such as the HTTP and HTTPS URI schemes, are also | |
applicable in HTTP/2, but the expression of those semantics for this protocol are defined | |
in the sections below. | |
</t> | |
<section anchor="HttpSequence" title="HTTP Request/Response Exchange"> | |
<t> | |
A client sends an HTTP request on a new stream, using a previously unused <xref | |
target="StreamIdentifiers">stream identifier</xref>. A server sends an HTTP response on | |
the same stream as the request. | |
</t> | |
<t> | |
An HTTP message (request or response) consists of: | |
<list style="numbers"> | |
<t> | |
for a response only, zero or more <x:ref>HEADERS</x:ref> frames (each followed by zero | |
or more <x:ref>CONTINUATION</x:ref> frames) containing the message headers of | |
informational (1xx) HTTP responses (see <xref target="RFC7230" x:fmt="," | |
x:rel="#header.fields"/> and <xref target="RFC7231" x:fmt="," x:rel="#status.1xx"/>), | |
and | |
</t> | |
<t> | |
one <x:ref>HEADERS</x:ref> frame (followed by zero or more <x:ref>CONTINUATION</x:ref> | |
frames) containing the message headers (see <xref target="RFC7230" x:fmt="," | |
x:rel="#header.fields"/>), and | |
</t> | |
<t> | |
zero or more <x:ref>DATA</x:ref> frames containing the message payload (see <xref | |
target="RFC7230" x:fmt="," x:rel="#message.body"/>), and | |
</t> | |
<t> | |
optionally, one <x:ref>HEADERS</x:ref> frame, followed by zero or more | |
<x:ref>CONTINUATION</x:ref> frames containing the trailer-part, if present (see <xref | |
target="RFC7230" x:fmt="," x:rel="#chunked.trailer.part"/>). | |
</t> | |
</list> | |
The last frame in the sequence bears an END_STREAM flag, noting that a | |
<x:ref>HEADERS</x:ref> frame bearing the END_STREAM flag can be followed by | |
<x:ref>CONTINUATION</x:ref> frames that carry any remaining portions of the header block. | |
</t> | |
<t> | |
Other frames (from any stream) MUST NOT occur between either <x:ref>HEADERS</x:ref> frame | |
and any <x:ref>CONTINUATION</x:ref> frames that might follow. | |
</t> | |
<t> | |
Trailing header fields are carried in a header block that also terminates the stream. | |
That is, a sequence starting with a <x:ref>HEADERS</x:ref> frame, followed by zero or more | |
<x:ref>CONTINUATION</x:ref> frames, where the <x:ref>HEADERS</x:ref> frame bears an | |
END_STREAM flag. Header blocks after the first that do not terminate the stream are not | |
part of an HTTP request or response. | |
</t> | |
<t> | |
A <x:ref>HEADERS</x:ref> frame (and associated <x:ref>CONTINUATION</x:ref> frames) can | |
only appear at the start or end of a stream. An endpoint that receives a | |
<x:ref>HEADERS</x:ref> frame without the END_STREAM flag set after receiving a final | |
(non-informational) status code MUST treat the corresponding request or response as <xref | |
target="malformed">malformed</xref>. | |
</t> | |
<t> | |
An HTTP request/response exchange fully consumes a single stream. A request starts with | |
the <x:ref>HEADERS</x:ref> frame that puts the stream into an "open" state. The request | |
ends with a frame bearing END_STREAM, which causes the stream to become "half closed | |
(local)" for the client and "half closed (remote)" for the server. A response starts with | |
a <x:ref>HEADERS</x:ref> frame and ends with a frame bearing END_STREAM, which places the | |
stream in the "closed" state. | |
<!-- Yes, the response might be completed before the request does, but that's not a detail | |
we need to expand upon. It's complicated enough explaining this as it is. --> | |
</t> | |
<section anchor="informational-responses" title="Upgrading From HTTP/2"> | |
<t> | |
HTTP/2 removes support for the 101 (Switching Protocols) informational status code | |
(<xref target="RFC7231" x:fmt="," x:rel="#status.101"/>). | |
</t> | |
<t> | |
The semantics of 101 (Switching Protocols) aren't applicable to a multiplexed protocol. | |
Alternative protocols are able to use the same mechanisms that HTTP/2 uses to negotiate | |
their use (see <xref target="starting"/>). | |
</t> | |
</section> | |
<section anchor="HttpHeaders" title="HTTP Header Fields"> | |
<t> | |
HTTP header fields carry information as a series of key-value pairs. For a listing of | |
registered HTTP headers, see the Message Header Field Registry maintained at <eref | |
target="https://www.iana.org/assignments/message-headers"/>. | |
</t> | |
<section anchor="PseudoHeaderFields" title="Pseudo-Header Fields"> | |
<t> | |
While HTTP/1.x used the message start-line (see <xref target="RFC7230" x:fmt="," | |
x:rel="#start.line"/>) to convey the target URI and method of the request, and the | |
status code for the response, HTTP/2 uses special pseudo-header fields beginning with | |
':' character (ASCII 0x3a) for this purpose. | |
</t> | |
<t> | |
Pseudo-header fields are not HTTP header fields. Endpoints MUST NOT generate | |
pseudo-header fields other than those defined in this document. | |
</t> | |
<t> | |
Pseudo-header fields are only valid in the context in which they are defined. | |
Pseudo-header fields defined for requests MUST NOT appear in responses; pseudo-header | |
fields defined for responses MUST NOT appear in requests. Pseudo-header fields MUST | |
NOT appear in trailers. Endpoints MUST treat a request or response that contains | |
undefined or invalid pseudo-header fields as <xref | |
target="malformed">malformed</xref>. | |
</t> | |
<t> | |
Just as in HTTP/1.x, header field names are strings of ASCII characters that are | |
compared in a case-insensitive fashion. However, header field names MUST be converted | |
to lowercase prior to their encoding in HTTP/2. A request or response containing | |
uppercase header field names MUST be treated as <xref | |
target="malformed">malformed</xref>. | |
</t> | |
<t> | |
All pseudo-header fields MUST appear in the header block before regular header fields. | |
Any request or response that contains a pseudo-header field that appears in a header | |
block after a regular header field MUST be treated as <xref | |
target="malformed">malformed</xref>. | |
</t> | |
</section> | |
<section title="Connection-Specific Header Fields"> | |
<t> | |
HTTP/2 does not use the <spanx style="verb">Connection</spanx> header field to | |
indicate connection-specific header fields; in this protocol, connection-specific | |
metadata is conveyed by other means. An endpoint MUST NOT generate a HTTP/2 message | |
containing connection-specific header fields; any message containing | |
connection-specific header fields MUST be treated as <xref | |
target="malformed">malformed</xref>. | |
</t> | |
<t> | |
This means that an intermediary transforming an HTTP/1.x message to HTTP/2 will need | |
to remove any header fields nominated by the Connection header field, along with the | |
Connection header field itself. Such intermediaries SHOULD also remove other | |
connection-specific header fields, such as Keep-Alive, Proxy-Connection, | |
Transfer-Encoding and Upgrade, even if they are not nominated by Connection. | |
</t> | |
<t> | |
One exception to this is the TE header field, which MAY be present in an HTTP/2 | |
request, but when it is MUST NOT contain any value other than "trailers". | |
</t> | |
<t> | |
<list style="hanging"> | |
<t hangText="Note:"> | |
HTTP/2 purposefully does not support upgrade to another protocol. The handshake | |
methods described in <xref target="starting"/> are believed sufficient to | |
negotiate the use of alternative protocols. | |
</t> | |
</list> | |
</t> | |
</section> | |
<section anchor="HttpRequest" title="Request Pseudo-Header Fields"> | |
<t> | |
The following pseudo-header fields are defined for HTTP/2 requests: | |
<list style="symbols"> | |
<x:lt> | |
<t> | |
The <spanx style="verb">:method</spanx> pseudo-header field includes the HTTP | |
method (<xref target="RFC7231" x:fmt="," x:rel="#methods"/>). | |
</t> | |
</x:lt> | |
<x:lt> | |
<t> | |
The <spanx style="verb">:scheme</spanx> pseudo-header field includes the scheme | |
portion of the target URI (<xref target="RFC3986" x:fmt="," x:sec="3.1"/>). | |
</t> | |
<t> | |
<spanx style="verb">:scheme</spanx> is not restricted to <spanx | |
style="verb">http</spanx> and <spanx style="verb">https</spanx> schemed URIs. A | |
proxy or gateway can translate requests for non-HTTP schemes, enabling the use | |
of HTTP to interact with non-HTTP services. | |
</t> | |
</x:lt> | |
<x:lt> | |
<t> | |
The <spanx style="verb">:authority</spanx> pseudo-header field includes the | |
authority portion of the target URI (<xref target="RFC3986" x:fmt="," | |
x:sec="3.2"/>). The authority MUST NOT include the deprecated <spanx | |
style="verb">userinfo</spanx> subcomponent for <spanx style="verb">http</spanx> | |
or <spanx style="verb">https</spanx> schemed URIs. | |
</t> | |
<t> | |
To ensure that the HTTP/1.1 request line can be reproduced accurately, this | |
pseudo-header field MUST be omitted when translating from an HTTP/1.1 request | |
that has a request target in origin or asterisk form (see <xref | |
target="RFC7230" x:fmt="," x:rel="#request-target"/>). Clients that generate | |
HTTP/2 requests directly SHOULD use the <spanx>:authority</spanx> pseudo-header | |
field instead of the <spanx style="verb">Host</spanx> header field. An | |
intermediary that converts an HTTP/2 request to HTTP/1.1 MUST create a <spanx | |
style="verb">Host</spanx> header field if one is not present in a request by | |
copying the value of the <spanx style="verb">:authority</spanx> pseudo-header | |
field. | |
</t> | |
</x:lt> | |
<x:lt> | |
<t> | |
The <spanx style="verb">:path</spanx> pseudo-header field includes the path and | |
query parts of the target URI (the <spanx style="verb">path-absolute</spanx> | |
production from <xref target="RFC3986"/> and optionally a '?' character | |
followed by the <spanx style="verb">query</spanx> production, see <xref | |
target="RFC3986" x:fmt="," x:sec="3.3"/> and <xref target="RFC3986" x:fmt="," | |
x:sec="3.4"/>). A request in asterisk form includes the value '*' for the | |
<spanx style="verb">:path</spanx> pseudo-header field. | |
</t> | |
<t> | |
This pseudo-header field MUST NOT be empty for <spanx style="verb">http</spanx> | |
or <spanx style="verb">https</spanx> URIs; <spanx style="verb">http</spanx> or | |
<spanx style="verb">https</spanx> URIs that do not contain a path component | |
MUST include a value of '/'. The exception to this rule is an OPTIONS request | |
for an <spanx style="verb">http</spanx> or <spanx style="verb">https</spanx> | |
URI that does not include a path component; these MUST include a <spanx | |
style="verb">:path</spanx> pseudo-header field with a value of '*' (see <xref | |
target="RFC7230" x:fmt="," x:rel="#asterisk-form"/>). | |
</t> | |
</x:lt> | |
</list> | |
</t> | |
<t> | |
All HTTP/2 requests MUST include exactly one valid value for the <spanx | |
style="verb">:method</spanx>, <spanx style="verb">:scheme</spanx>, and <spanx | |
style="verb">:path</spanx> pseudo-header fields, unless it is a <xref | |
target="CONNECT">CONNECT request</xref>. An HTTP request that omits mandatory | |
pseudo-header fields is <xref target="malformed">malformed</xref>. | |
</t> | |
<t> | |
HTTP/2 does not define a way to carry the version identifier that is included in the | |
HTTP/1.1 request line. | |
</t> | |
</section> | |
<section anchor="HttpResponse" title="Response Pseudo-Header Fields"> | |
<t> | |
For HTTP/2 responses, a single <spanx style="verb">:status</spanx> pseudo-header | |
field is defined that carries the HTTP status code field (see <xref target="RFC7231" | |
x:fmt="," x:rel="#status.codes"/>). This pseudo-header field MUST be included in all | |
responses, otherwise the response is <xref target="malformed">malformed</xref>. | |
</t> | |
<t> | |
HTTP/2 does not define a way to carry the version or reason phrase that is included in | |
an HTTP/1.1 status line. | |
</t> | |
</section> | |
<section anchor="CompressCookie" title="Compressing the Cookie Header Field"> | |
<t> | |
The <xref target="COOKIE">Cookie header field</xref> can carry a significant amount of | |
redundant data. | |
</t> | |
<t> | |
The Cookie header field uses a semi-colon (";") to delimit cookie-pairs (or "crumbs"). | |
This header field doesn't follow the list construction rules in HTTP (see <xref | |
target="RFC7230" x:fmt="," x:rel="#field.order"/>), which prevents cookie-pairs from | |
being separated into different name-value pairs. This can significantly reduce | |
compression efficiency as individual cookie-pairs are updated. | |
</t> | |
<t> | |
To allow for better compression efficiency, the Cookie header field MAY be split into | |
separate header fields, each with one or more cookie-pairs. If there are multiple | |
Cookie header fields after decompression, these MUST be concatenated into a single | |
octet string using the two octet delimiter of 0x3B, 0x20 (the ASCII string "; ") | |
before being passed into a non-HTTP/2 context, such as an HTTP/1.1 connection, or a | |
generic HTTP server application. | |
</t> | |
<figure> | |
<preamble> | |
Therefore, the following two lists of Cookie header fields are semantically | |
equivalent. | |
</preamble> | |
<artwork type="inline"><![CDATA[ | |
cookie: a=b; c=d; e=f | |
cookie: a=b | |
cookie: c=d | |
cookie: e=f | |
]]></artwork> | |
</figure> | |
</section> | |
<section anchor="malformed" title="Malformed Requests and Responses"> | |
<t> | |
A malformed request or response is one that is an otherwise valid sequence of HTTP/2 | |
frames, but is otherwise invalid due to the presence of extraneous frames, prohibited | |
header fields, the absence of mandatory header fields, or the inclusion of uppercase | |
header field names. | |
</t> | |
<t> | |
A request or response that includes an entity body can include a <spanx | |
style="verb">content-length</spanx> header field. A request or response is also | |
malformed if the value of a <spanx style="verb">content-length</spanx> header field | |
does not equal the sum of the <x:ref>DATA</x:ref> frame payload lengths that form the | |
body. A response that is defined to have no payload, as described in <xref | |
target="RFC7230" x:fmt="," x:rel="#header.content-length"/>, can have a non-zero | |
<spanx style="verb">content-length</spanx> header field, even though no content is | |
included in <x:ref>DATA</x:ref> frames. | |
</t> | |
<t> | |
Intermediaries that process HTTP requests or responses (i.e., any intermediary not | |
acting as a tunnel) MUST NOT forward a malformed request or response. Malformed | |
requests or responses that are detected MUST be treated as a <xref | |
target="StreamErrorHandler">stream error</xref> of type <x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
For malformed requests, a server MAY send an HTTP response prior to closing or | |
resetting the stream. Clients MUST NOT accept a malformed response. Note that these | |
requirements are intended to protect against several types of common attacks against | |
HTTP; they are deliberately strict, because being permissive can expose | |
implementations to these vulnerabilities. | |
</t> | |
</section> | |
</section> | |
<section title="Examples"> | |
<t> | |
This section shows HTTP/1.1 requests and responses, with illustrations of equivalent | |
HTTP/2 requests and responses. | |
</t> | |
<t> | |
An HTTP GET request includes request header fields and no body and is therefore | |
transmitted as a single <x:ref>HEADERS</x:ref> frame, followed by zero or more | |
<x:ref>CONTINUATION</x:ref> frames containing the serialized block of request header | |
fields. The <x:ref>HEADERS</x:ref> frame in the following has both the END_HEADERS and | |
END_STREAM flags set; no <x:ref>CONTINUATION</x:ref> frames are sent: | |
</t> | |
<figure> | |
<artwork type="inline"><![CDATA[ | |
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 | |
]]></artwork> | |
</figure> | |
<t> | |
Similarly, a response that includes only response header fields is transmitted as a | |
<x:ref>HEADERS</x:ref> frame (again, followed by zero or more | |
<x:ref>CONTINUATION</x:ref> frames) containing the serialized block of response header | |
fields. | |
</t> | |
<figure> | |
<artwork type="inline"><![CDATA[ | |
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 ... | |
]]></artwork> | |
</figure> | |
<t> | |
An HTTP POST request that includes request header fields and payload data is transmitted | |
as one <x:ref>HEADERS</x:ref> frame, followed by zero or more | |
<x:ref>CONTINUATION</x:ref> frames containing the request header fields, followed by one | |
or more <x:ref>DATA</x:ref> frames, with the last <x:ref>CONTINUATION</x:ref> (or | |
<x:ref>HEADERS</x:ref>) frame having the END_HEADERS flag set and the final | |
<x:ref>DATA</x:ref> frame having the END_STREAM flag set: | |
</t> | |
<figure> | |
<artwork type="inline"><![CDATA[ | |
POST /resource HTTP/1.1 HEADERS | |