<?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 | |
Host: example.org ==> - END_STREAM | |
Content-Type: image/jpeg - END_HEADERS | |
Content-Length: 123 :method = POST | |
:path = /resource | |
{binary data} :scheme = https | |
CONTINUATION | |
+ END_HEADERS | |
content-type = image/jpeg | |
host = example.org | |
content-length = 123 | |
DATA | |
+ END_STREAM | |
{binary data} | |
]]></artwork> | |
<postamble> | |
Note that data contributing to any given header field could be spread between header | |
block fragments. The allocation of header fields to frames in this example is | |
illustrative only. | |
</postamble> | |
</figure> | |
<t> | |
A response that includes header fields and payload data is transmitted as a | |
<x:ref>HEADERS</x:ref> frame, followed by zero or more <x:ref>CONTINUATION</x:ref> | |
frames, followed by one or more <x:ref>DATA</x:ref> frames, with the last | |
<x:ref>DATA</x:ref> frame in the sequence having the END_STREAM flag set: | |
</t> | |
<figure> | |
<artwork type="inline"><![CDATA[ | |
HTTP/1.1 200 OK HEADERS | |
Content-Type: image/jpeg ==> - END_STREAM | |
Content-Length: 123 + END_HEADERS | |
:status = 200 | |
{binary data} content-type = image/jpeg | |
content-length = 123 | |
DATA | |
+ END_STREAM | |
{binary data} | |
]]></artwork> | |
</figure> | |
<t> | |
Trailing header fields are sent as a header block after both the request or response | |
header block and all the <x:ref>DATA</x:ref> frames have been sent. The | |
<x:ref>HEADERS</x:ref> frame starting the trailers header block has the END_STREAM flag | |
set. | |
</t> | |
<figure> | |
<artwork type="inline"><![CDATA[ | |
HTTP/1.1 200 OK HEADERS | |
Content-Type: image/jpeg ==> - END_STREAM | |
Transfer-Encoding: chunked + END_HEADERS | |
Trailer: Foo :status = 200 | |
content-length = 123 | |
123 content-type = image/jpeg | |
{binary data} trailer = Foo | |
0 | |
Foo: bar DATA | |
- END_STREAM | |
{binary data} | |
HEADERS | |
+ END_STREAM | |
+ END_HEADERS | |
foo = bar | |
]]></artwork> | |
</figure> | |
<figure> | |
<preamble> | |
An informational response using a 1xx status code other than 101 is transmitted as a | |
<x:ref>HEADERS</x:ref> frame, followed by zero or more <x:ref>CONTINUATION</x:ref> | |
frames: | |
</preamble> | |
<artwork type="inline"><![CDATA[ | |
HTTP/1.1 103 BAR HEADERS | |
Extension-Field: bar ==> - END_STREAM | |
+ END_HEADERS | |
:status = 103 | |
extension-field = bar | |
]]></artwork> | |
</figure> | |
</section> | |
<section anchor="Reliability" title="Request Reliability Mechanisms in HTTP/2"> | |
<t> | |
In HTTP/1.1, an HTTP client is unable to retry a non-idempotent request when an error | |
occurs, because there is no means to determine the nature of the error. It is possible | |
that some server processing occurred prior to the error, which could result in | |
undesirable effects if the request were reattempted. | |
</t> | |
<t> | |
HTTP/2 provides two mechanisms for providing a guarantee to a client that a request has | |
not been processed: | |
<list style="symbols"> | |
<t> | |
The <x:ref>GOAWAY</x:ref> frame indicates the highest stream number that might have | |
been processed. Requests on streams with higher numbers are therefore guaranteed to | |
be safe to retry. | |
</t> | |
<t> | |
The <x:ref>REFUSED_STREAM</x:ref> error code can be included in a | |
<x:ref>RST_STREAM</x:ref> frame to indicate that the stream is being closed prior to | |
any processing having occurred. Any request that was sent on the reset stream can | |
be safely retried. | |
</t> | |
</list> | |
</t> | |
<t> | |
Requests that have not been processed have not failed; clients MAY automatically retry | |
them, even those with non-idempotent methods. | |
</t> | |
<t> | |
A server MUST NOT indicate that a stream has not been processed unless it can guarantee | |
that fact. If frames that are on a stream are passed to the application layer for any | |
stream, then <x:ref>REFUSED_STREAM</x:ref> MUST NOT be used for that stream, and a | |
<x:ref>GOAWAY</x:ref> frame MUST include a stream identifier that is greater than or | |
equal to the given stream identifier. | |
</t> | |
<t> | |
In addition to these mechanisms, the <x:ref>PING</x:ref> frame provides a way for a | |
client to easily test a connection. Connections that remain idle can become broken as | |
some middleboxes (for instance, network address translators, or load balancers) silently | |
discard connection bindings. The <x:ref>PING</x:ref> frame allows a client to safely | |
test whether a connection is still active without sending a request. | |
</t> | |
</section> | |
</section> | |
<section anchor="PushResources" title="Server Push"> | |
<t> | |
HTTP/2 allows a server to pre-emptively send (or "push") responses (along with | |
corresponding "promised" requests) to a client in association with a previous | |
client-initiated request. This can be useful when the server knows the client will need | |
to have those responses available in order to fully process the response to the original | |
request. | |
</t> | |
<t> | |
Pushing additional message exchanges in this fashion is optional, and is negotiated | |
between individual endpoints. The <x:ref>SETTINGS_ENABLE_PUSH</x:ref> setting can be set | |
to 0 to indicate that server push is disabled. | |
</t> | |
<t> | |
Promised requests MUST be cacheable (see <xref target="RFC7231" x:fmt="," | |
x:rel="#cacheable.methods"/>), MUST be safe (see <xref target="RFC7231" x:fmt="," | |
x:rel="#safe.methods"/>) and MUST NOT include a request body. Clients that receive a | |
promised request that is not cacheable, unsafe or that includes a request body MUST | |
reset the stream with a <xref target="StreamErrorHandler">stream error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
Pushed responses that are cacheable (see <xref target="RFC7234" x:fmt="," | |
x:rel="#response.cacheability"/>) can be stored by the client, if it implements a HTTP | |
cache. Pushed responses are considered successfully validated on the origin server (e.g., | |
if the "no-cache" cache response directive <xref target="RFC7234" x:fmt="," | |
x:rel="#cache-response-directive"/> is present) while the stream identified by the | |
promised stream ID is still open. | |
</t> | |
<t> | |
Pushed responses that are not cacheable MUST NOT be stored by any HTTP cache. They MAY | |
be made available to the application separately. | |
</t> | |
<t> | |
An intermediary can receive pushes from the server and choose not to forward them on to | |
the client. In other words, how to make use of the pushed information is up to that | |
intermediary. Equally, the intermediary might choose to make additional pushes to the | |
client, without any action taken by the server. | |
</t> | |
<t> | |
A client cannot push. Thus, servers 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>. Clients MUST reject any attempt to | |
change the <x:ref>SETTINGS_ENABLE_PUSH</x:ref> setting to a value other than 0 by treating | |
the message as a <xref target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<section anchor="PushRequests" title="Push Requests"> | |
<t> | |
Server push is semantically equivalent to a server responding to a request; however, in | |
this case that request is also sent by the server, as a <x:ref>PUSH_PROMISE</x:ref> | |
frame. | |
</t> | |
<t> | |
The <x:ref>PUSH_PROMISE</x:ref> frame includes a header block that contains a complete | |
set of request header fields that the server attributes to the request. It is not | |
possible to push a response to a request that includes a request body. | |
</t> | |
<t> | |
Pushed responses are always associated with an explicit request from the client. The | |
<x:ref>PUSH_PROMISE</x:ref> frames sent by the server are sent on that explicit | |
request's stream. The <x:ref>PUSH_PROMISE</x:ref> frame also includes a promised stream | |
identifier, chosen from the stream identifiers available to the server (see <xref | |
target="StreamIdentifiers"/>). | |
</t> | |
<t> | |
The header fields in <x:ref>PUSH_PROMISE</x:ref> and any subsequent | |
<x:ref>CONTINUATION</x:ref> frames MUST be a valid and complete set of <xref | |
target="HttpRequest">request header fields</xref>. The server MUST include a method in | |
the <spanx style="verb">:method</spanx> header field that is safe and cacheable. If a | |
client receives a <x:ref>PUSH_PROMISE</x:ref> that does not include a complete and valid | |
set of header fields, or the <spanx style="verb">:method</spanx> header field identifies | |
a method that is not safe, it MUST respond with a <xref | |
target="StreamErrorHandler">stream error</xref> of type <x:ref>PROTOCOL_ERROR</x:ref>. | |
</t> | |
<t> | |
The server SHOULD send <x:ref>PUSH_PROMISE</x:ref> (<xref target="PUSH_PROMISE"/>) | |
frames prior to sending any frames that reference the promised responses. This avoids a | |
race where clients issue requests prior to receiving any <x:ref>PUSH_PROMISE</x:ref> | |
frames. | |
</t> | |
<t> | |
For example, if the server receives a request for a document containing embedded links | |
to multiple image files, and the server chooses to push those additional images to the | |
client, sending push promises before the <x:ref>DATA</x:ref> frames that contain the | |
image links ensures that the client is able to see the promises before discovering | |
embedded links. Similarly, if the server pushes responses referenced by the header block | |
(for instance, in Link header fields), sending the push promises before sending the | |
header block ensures that clients do not request them. | |
</t> | |
<t> | |
<x:ref>PUSH_PROMISE</x:ref> frames MUST NOT be sent by the client. | |
</t> | |
<t> | |
<x:ref>PUSH_PROMISE</x:ref> frames can be sent by the server in response to any | |
client-initiated stream, but the stream MUST be in either the "open" or "half closed | |
(remote)" state with respect to the server. <x:ref>PUSH_PROMISE</x:ref> frames are | |
interspersed with the frames that comprise a response, though they cannot be | |
interspersed with <x:ref>HEADERS</x:ref> and <x:ref>CONTINUATION</x:ref> frames that | |
comprise a single header block. | |
</t> | |
<t> | |
Sending a <x:ref>PUSH_PROMISE</x:ref> frame creates a new stream and puts the stream | |
into the “reserved (local)” state for the server and the “reserved (remote)” state for | |
the client. | |
</t> | |
</section> | |
<section anchor="PushResponses" title="Push Responses"> | |
<t> | |
After sending the <x:ref>PUSH_PROMISE</x:ref> frame, the server can begin delivering the | |
pushed response as a <xref target="HttpResponse">response</xref> on a server-initiated | |
stream that uses the promised stream identifier. The server uses this stream to | |
transmit an HTTP response, using the same sequence of frames as defined in <xref | |
target="HttpSequence"/>. This stream becomes <xref target="StreamStates">"half closed" | |
to the client</xref> after the initial <x:ref>HEADERS</x:ref> frame is sent. | |
</t> | |
<t> | |
Once a client receives a <x:ref>PUSH_PROMISE</x:ref> frame and chooses to accept the | |
pushed response, the client SHOULD NOT issue any requests for the promised response | |
until after the promised stream has closed. | |
</t> | |
<t> | |
If the client determines, for any reason, that it does not wish to receive the pushed | |
response from the server, or if the server takes too long to begin sending the promised | |
response, the client can send an <x:ref>RST_STREAM</x:ref> frame, using either the | |
<x:ref>CANCEL</x:ref> or <x:ref>REFUSED_STREAM</x:ref> codes, and referencing the pushed | |
stream's identifier. | |
</t> | |
<t> | |
A client can use the <x:ref>SETTINGS_MAX_CONCURRENT_STREAMS</x:ref> setting to limit the | |
number of responses that can be concurrently pushed by a server. Advertising a | |
<x:ref>SETTINGS_MAX_CONCURRENT_STREAMS</x:ref> value of zero disables server push by | |
preventing the server from creating the necessary streams. This does not prohibit a | |
server from sending <x:ref>PUSH_PROMISE</x:ref> frames; clients need to reset any | |
promised streams that are not wanted. | |
</t> | |
<t> | |
Clients receiving a pushed response MUST validate that either the server is | |
authoritative (see <xref target="authority"/>), or the proxy that provided the pushed | |
response is configured for the corresponding request. For example, a server that offers | |
a certificate for only the <spanx style="verb">example.com</spanx> DNS-ID or Common Name | |
is not permitted to push a response for <spanx | |
style="verb">https://www.example.org/doc</spanx>. | |
</t> | |
<t> | |
The response for a <x:ref>PUSH_PROMISE</x:ref> stream begins with a | |
<x:ref>HEADERS</x:ref> frame, which immediately puts the stream into the “half closed | |
(remote)” state for the server and “half closed (local)” state for the client, and ends | |
with a frame bearing END_STREAM, which places the stream in the "closed" state. | |
<list style="hanging"> | |
<t hangText="Note:"> | |
The client never sends a frame with the END_STREAM flag for a server push. | |
</t> | |
</list> | |
</t> | |
</section> | |
</section> | |
<section anchor="CONNECT" title="The CONNECT Method"> | |
<t> | |
In HTTP/1.x, the pseudo-method CONNECT (<xref target="RFC7231" x:fmt="," | |
x:rel="#CONNECT"/>) is used to convert an HTTP connection into a tunnel to a remote host. | |
CONNECT is primarily used with HTTP proxies to establish a TLS session with an origin | |
server for the purposes of interacting with <spanx style="verb">https</spanx> resources. | |
</t> | |
<t> | |
In HTTP/2, the CONNECT method is used to establish a tunnel over a single HTTP/2 stream to | |
a remote host, for similar purposes. The HTTP header field mapping works as defined in | |
<xref target="HttpRequest">Request Header Fields</xref>, with a few | |
differences. Specifically: | |
<list style="symbols"> | |
<t> | |
The <spanx style="verb">:method</spanx> header field is set to <spanx | |
style="verb">CONNECT</spanx>. | |
</t> | |
<t> | |
The <spanx style="verb">:scheme</spanx> and <spanx style="verb">:path</spanx> header | |
fields MUST be omitted. | |
</t> | |
<t> | |
The <spanx style="verb">:authority</spanx> header field contains the host and port to | |
connect to (equivalent to the authority-form of the request-target of CONNECT | |
requests, see <xref target="RFC7230" x:fmt="," x:rel="#request-target"/>). | |
</t> | |
</list> | |
</t> | |
<t> | |
A proxy that supports CONNECT establishes a <xref target="TCP">TCP connection</xref> to | |
the server identified in the <spanx style="verb">:authority</spanx> header field. Once | |
this connection is successfully established, the proxy sends a <x:ref>HEADERS</x:ref> | |
frame containing a 2xx series status code to the client, as defined in <xref | |
target="RFC7231" x:fmt="," x:rel="#CONNECT"/>. | |
</t> | |
<t> | |
After the initial <x:ref>HEADERS</x:ref> frame sent by each peer, all subsequent | |
<x:ref>DATA</x:ref> frames correspond to data sent on the TCP connection. The payload of | |
any <x:ref>DATA</x:ref> frames sent by the client is transmitted by the proxy to the TCP | |
server; data received from the TCP server is assembled into <x:ref>DATA</x:ref> frames by | |
the proxy. Frame types other than <x:ref>DATA</x:ref> or stream management frames | |
(<x:ref>RST_STREAM</x:ref>, <x:ref>WINDOW_UPDATE</x:ref>, and <x:ref>PRIORITY</x:ref>) | |
MUST NOT be sent on a connected stream, and MUST be treated as a <xref | |
target="StreamErrorHandler">stream error</xref> if received. | |
</t> | |
<t> | |
The TCP connection can be closed by either peer. The END_STREAM flag on a | |
<x:ref>DATA</x:ref> frame is treated as being equivalent to the TCP FIN bit. A client is | |
expected to send a <x:ref>DATA</x:ref> frame with the END_STREAM flag set after receiving | |
a frame bearing the END_STREAM flag. A proxy that receives a <x:ref>DATA</x:ref> frame | |
with the END_STREAM flag set sends the attached data with the FIN bit set on the last TCP | |
segment. A proxy that receives a TCP segment with the FIN bit set sends a | |
<x:ref>DATA</x:ref> frame with the END_STREAM flag set. Note that the final TCP segment | |
or <x:ref>DATA</x:ref> frame could be empty. | |
</t> | |
<t> | |
A TCP connection error is signaled with <x:ref>RST_STREAM</x:ref>. A proxy treats any | |
error in the TCP connection, which includes receiving a TCP segment with the RST bit set, | |
as a <xref target="StreamErrorHandler">stream error</xref> of type | |
<x:ref>CONNECT_ERROR</x:ref>. Correspondingly, a proxy MUST send a TCP segment with the | |
RST bit set if it detects an error with the stream or the HTTP/2 connection. | |
</t> | |
</section> | |
</section> | |
<section anchor="HttpExtra" title="Additional HTTP Requirements/Considerations"> | |
<t> | |
This section outlines attributes of the HTTP protocol that improve interoperability, reduce | |
exposure to known security vulnerabilities, or reduce the potential for implementation | |
variation. | |
</t> | |
<section title="Connection Management"> | |
<t> | |
HTTP/2 connections are persistent. For best performance, it is expected clients will not | |
close connections until it is determined that no further communication with a server is | |
necessary (for example, when a user navigates away from a particular web page), or until | |
the server closes the connection. | |
</t> | |
<t> | |
Clients SHOULD NOT open more than one HTTP/2 connection to a given host and port pair, | |
where host is derived from a URI, a selected <xref target="ALT-SVC">alternative | |
service</xref>, or a configured proxy. | |
</t> | |
<t> | |
A client can create additional connections as replacements, either to replace connections | |
that are near to exhausting the available <xref target="StreamIdentifiers">stream | |
identifier space</xref>, to refresh the keying material for a TLS connection, or to | |
replace connections that have encountered <xref | |
target="ConnectionErrorHandler">errors</xref>. | |
</t> | |
<t> | |
A client MAY open multiple connections to the same IP address and TCP port using different | |
<xref target="TLS-EXT">Server Name Indication</xref> values or to provide different TLS | |
client certificates, but SHOULD avoid creating multiple connections with the same | |
configuration. | |
</t> | |
<t> | |
Servers are encouraged to maintain open connections for as long as possible, but are | |
permitted to terminate idle connections if necessary. When either endpoint chooses to | |
close the transport-layer TCP connection, the terminating endpoint SHOULD first send a | |
<x:ref>GOAWAY</x:ref> (<xref target="GOAWAY"/>) frame so that both endpoints can reliably | |
determine whether previously sent frames have been processed and gracefully complete or | |
terminate any necessary remaining tasks. | |
</t> | |
<section anchor="reuse" title="Connection Reuse"> | |
<t> | |
Connections that are made to an origin servers, either directly or through a tunnel | |
created using the <xref target="CONNECT">CONNECT method</xref> MAY be reused for | |
requests with multiple different URI authority components. A connection can be reused | |
as long as the origin server is <xref target="authority">authoritative</xref>. For | |
<spanx style="verb">http</spanx> resources, this depends on the host having resolved to | |
the same IP address. | |
</t> | |
<t> | |
For <spanx style="verb">https</spanx> resources, connection reuse additionally depends | |
on having a certificate that is valid for the host in the URI. An origin server might | |
offer a certificate with multiple <spanx style="verb">subjectAltName</spanx> attributes, | |
or names with wildcards, one of which is valid for the authority in the URI. For | |
example, a certificate with a <spanx style="verb">subjectAltName</spanx> of <spanx | |
style="verb">*.example.com</spanx> might permit the use of the same connection for | |
requests to URIs starting with <spanx style="verb">https://a.example.com/</spanx> and | |
<spanx style="verb">https://b.example.com/</spanx>. | |
</t> | |
<t> | |
In some deployments, reusing a connection for multiple origins can result in requests | |
being directed to the wrong origin server. For example, TLS termination might be | |
performed by a middlebox that uses the TLS <xref target="TLS-EXT">Server Name Indication | |
(SNI)</xref> extension to select an origin server. This means that it is possible | |
for clients to send confidential information to servers that might not be the intended | |
target for the request, even though the server is otherwise authoritative. | |
</t> | |
<t> | |
A server that does not wish clients to reuse connections can indicate that it is not | |
authoritative for a request by sending a 421 (Misdirected Request) status code in response | |
to the request (see <xref target="MisdirectedRequest"/>). | |
</t> | |
<t> | |
A client that is configured to use a proxy over HTTP/2 directs requests to that proxy | |
through a single connection. That is, all requests sent via a proxy reuse the | |
connection to the proxy. | |
</t> | |
</section> | |
<section anchor="MisdirectedRequest" title="The 421 (Misdirected Request) Status Code"> | |
<t> | |
The 421 (Misdirected Request) status code indicates that the request was directed at a | |
server that is not able to produce a response. This can be sent by a server that is not | |
configured to produce responses for the combination of scheme and authority that are | |
included in the request URI. | |
</t> | |
<t> | |
Clients receiving a 421 (Misdirected Request) response from a server MAY retry the | |
request - whether the request method is idempotent or not - over a different connection. | |
This is possible if a connection is reused (<xref target="reuse"/>) or if an alternative | |
service is selected (<xref target="ALT-SVC"/>). | |
</t> | |
<t> | |
This status code MUST NOT be generated by proxies. | |
</t> | |
<t> | |
A 421 response is cacheable by default; i.e., unless otherwise indicated by the method | |
definition or explicit cache controls (see <xref target="RFC7234" | |
x:rel="#heuristic.freshness" x:fmt="of"/>). | |
</t> | |
</section> | |
</section> | |
<section title="Use of TLS Features" anchor="TLSUsage"> | |
<t> | |
Implementations of HTTP/2 MUST support <xref target="TLS12">TLS 1.2</xref> for HTTP/2 over | |
TLS. The general TLS usage guidance in <xref target="TLSBCP"/> SHOULD be followed, with | |
some additional restrictions that are specific to HTTP/2. | |
</t> | |
<t> | |
An implementation of HTTP/2 over TLS MUST use TLS 1.2 or higher with the restrictions on | |
feature set and cipher suite described in this section. Due to implementation | |
limitations, it might not be possible to fail TLS negotiation. An endpoint MUST | |
immediately terminate an HTTP/2 connection that does not meet these minimum requirements | |
with a <xref target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>INADEQUATE_SECURITY</x:ref>. | |
</t> | |
<section anchor="TLSFeatures" title="TLS Features"> | |
<t> | |
The TLS implementation MUST support the <xref target="TLS-EXT">Server Name Indication | |
(SNI)</xref> extension to TLS. HTTP/2 clients MUST indicate the target domain name when | |
negotiating TLS. | |
</t> | |
<t> | |
The TLS implementation MUST disable compression. TLS compression can lead to the | |
exposure of information that would not otherwise be revealed <xref target="RFC3749"/>. | |
Generic compression is unnecessary since HTTP/2 provides compression features that are | |
more aware of context and therefore likely to be more appropriate for use for | |
performance, security or other reasons. | |
</t> | |
<t> | |
The TLS implementation MUST disable renegotiation. An endpoint MUST treat a TLS | |
renegotiation as a <xref target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>PROTOCOL_ERROR</x:ref>. Note that disabling renegotiation can result in | |
long-lived connections becoming unusable due to limits on the number of messages the | |
underlying cipher suite can encipher. | |
</t> | |
<t> | |
A client MAY use renegotiation to provide confidentiality protection for client | |
credentials offered in the handshake, but any renegotiation MUST occur prior to sending | |
the connection preface. A server SHOULD request a client certificate if it sees a | |
renegotiation request immediately after establishing a connection. | |
</t> | |
<t> | |
This effectively prevents the use of renegotiation in response to a request for a | |
specific protected resource. A future specification might provide a way to support this | |
use case. <!-- <cref> We are tracking this in a non-blocking fashion in issue #496 and | |
with a new draft. --> | |
</t> | |
</section> | |
<section title="TLS Cipher Suites"> | |
<t> | |
The set of TLS cipher suites that are permitted in HTTP/2 is restricted. HTTP/2 MUST | |
only be used with cipher suites that have ephemeral key exchange, such as the <xref | |
target="TLS12">ephemeral Diffie-Hellman (DHE)</xref> or the <xref | |
target="RFC4492">elliptic curve variant (ECDHE)</xref>. Ephemeral key exchange MUST | |
have a minimum size of 2048 bits for DHE or security level of 128 bits for ECDHE. | |
Clients MUST accept DHE sizes of up to 4096 bits. HTTP MUST NOT be used with cipher | |
suites that use stream or block ciphers. Authenticated Encryption with Additional Data | |
(AEAD) modes, such as the <xref target="RFC5288">Galois Counter Model (GCM) mode for | |
AES</xref> are acceptable. | |
</t> | |
<t> | |
The effect of these restrictions is that TLS 1.2 implementations could have | |
non-intersecting sets of available cipher suites, since these prevent the use of the | |
cipher suite that TLS 1.2 makes mandatory. To avoid this problem, implementations of | |
HTTP/2 that use TLS 1.2 MUST support TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 <xref | |
target="TLS-ECDHE"/> with P256 <xref target="FIPS186"/>. | |
</t> | |
<t> | |
Clients MAY advertise support of cipher suites that are prohibited by the above | |
restrictions in order to allow for connection to servers that do not support HTTP/2. | |
This enables a fallback to protocols without these constraints without the additional | |
latency imposed by using a separate connection for fallback. | |
</t> | |
</section> | |
</section> | |
</section> | |
<section anchor="security" title="Security Considerations"> | |
<section title="Server Authority" anchor="authority"> | |
<t> | |
HTTP/2 relies on the HTTP/1.1 definition of authority for determining whether a server is | |
authoritative in providing a given response, see <xref target="RFC7230" x:fmt="," | |
x:rel="#establishing.authority"/>. This relies on local name resolution for the "http" | |
URI scheme, and the authenticated server identity for the "https" scheme (see <xref | |
target="RFC2818" x:fmt="," x:sec="3"/>). | |
</t> | |
</section> | |
<section title="Cross-Protocol Attacks"> | |
<t> | |
In a cross-protocol attack, an attacker causes a client to initiate a transaction in one | |
protocol toward a server that understands a different protocol. An attacker might be able | |
to cause the transaction to appear as valid transaction in the second protocol. In | |
combination with the capabilities of the web context, this can be used to interact with | |
poorly protected servers in private networks. | |
</t> | |
<t> | |
Completing a TLS handshake with an ALPN identifier for HTTP/2 can be considered sufficient | |
protection against cross protocol attacks. ALPN provides a positive indication that a | |
server is willing to proceed with HTTP/2, which prevents attacks on other TLS-based | |
protocols. | |
</t> | |
<t> | |
The encryption in TLS makes it difficult for attackers to control the data which could be | |
used in a cross-protocol attack on a cleartext protocol. | |
</t> | |
<t> | |
The cleartext version of HTTP/2 has minimal protection against cross-protocol attacks. | |
The <xref target="ConnectionHeader">connection preface</xref> contains a string that is | |
designed to confuse HTTP/1.1 servers, but no special protection is offered for other | |
protocols. A server that is willing to ignore parts of an HTTP/1.1 request containing an | |
Upgrade header field in addition to the client connection preface could be exposed to a | |
cross-protocol attack. | |
</t> | |
</section> | |
<section title="Intermediary Encapsulation Attacks"> | |
<t> | |
HTTP/2 header field names and values are encoded as sequences of octets with a length | |
prefix. This enables HTTP/2 to carry any string of octets as the name or value of a | |
header field. An intermediary that translates HTTP/2 requests or responses into HTTP/1.1 | |
directly could permit the creation of corrupted HTTP/1.1 messages. An attacker might | |
exploit this behavior to cause the intermediary to create HTTP/1.1 messages with illegal | |
header fields, extra header fields, or even new messages that are entirely falsified. | |
</t> | |
<t> | |
Header field names or values that contain characters not permitted by HTTP/1.1, including | |
carriage return (ASCII 0xd) or line feed (ASCII 0xa) MUST NOT be translated verbatim by an | |
intermediary, as stipulated in <xref target="RFC7230" x:rel="#field.parsing" x:fmt=","/>. | |
</t> | |
<t> | |
Translation from HTTP/1.x to HTTP/2 does not produce the same opportunity to an attacker. | |
Intermediaries that perform translation to HTTP/2 MUST remove any instances of the <spanx | |
style="verb">obs-fold</spanx> production from header field values. | |
</t> | |
</section> | |
<section title="Cacheability of Pushed Responses"> | |
<t> | |
Pushed responses do not have an explicit request from the client; the request | |
is provided by the server in the <x:ref>PUSH_PROMISE</x:ref> frame. | |
</t> | |
<t> | |
Caching responses that are pushed is possible based on the guidance provided by the origin | |
server in the Cache-Control header field. However, this can cause issues if a single | |
server hosts more than one tenant. For example, a server might offer multiple users each | |
a small portion of its URI space. | |
</t> | |
<t> | |
Where multiple tenants share space on the same server, that server MUST ensure that | |
tenants are not able to push representations of resources that they do not have authority | |
over. Failure to enforce this would allow a tenant to provide a representation that would | |
be served out of cache, overriding the actual representation that the authoritative tenant | |
provides. | |
</t> | |
<t> | |
Pushed responses for which an origin server is not authoritative (see | |
<xref target="authority"/>) are never cached or used. | |
</t> | |
</section> | |
<section anchor="dos" title="Denial of Service Considerations"> | |
<t> | |
An HTTP/2 connection can demand a greater commitment of resources to operate than a | |
HTTP/1.1 connection. The use of header compression and flow control depend on a | |
commitment of resources for storing a greater amount of state. Settings for these | |
features ensure that memory commitments for these features are strictly bounded. | |
</t> | |
<t> | |
The number of <x:ref>PUSH_PROMISE</x:ref> frames is not constrained in the same fashion. | |
A client that accepts server push SHOULD limit the number of streams it allows to be in | |
the "reserved (remote)" state. Excessive number of server push streams can be treated as | |
a <xref target="StreamErrorHandler">stream error</xref> of type | |
<x:ref>ENHANCE_YOUR_CALM</x:ref>. | |
</t> | |
<t> | |
Processing capacity cannot be guarded as effectively as state capacity. | |
</t> | |
<t> | |
The <x:ref>SETTINGS</x:ref> frame can be abused to cause a peer to expend additional | |
processing time. This might be done by pointlessly changing SETTINGS parameters, setting | |
multiple undefined parameters, or changing the same setting multiple times in the same | |
frame. <x:ref>WINDOW_UPDATE</x:ref> or <x:ref>PRIORITY</x:ref> frames can be abused to | |
cause an unnecessary waste of resources. | |
</t> | |
<t> | |
Large numbers of small or empty frames can be abused to cause a peer to expend time | |
processing frame headers. Note however that some uses are entirely legitimate, such as | |
the sending of an empty <x:ref>DATA</x:ref> frame to end a stream. | |
</t> | |
<t> | |
Header compression also offers some opportunities to waste processing resources; see <xref | |
target="COMPRESSION" x:fmt="of" x:rel="#Security"/> for more details on potential abuses. | |
</t> | |
<t> | |
Limits in <x:ref>SETTINGS</x:ref> parameters cannot be reduced instantaneously, which | |
leaves an endpoint exposed to behavior from a peer that could exceed the new limits. In | |
particular, immediately after establishing a connection, limits set by a server are not | |
known to clients and could be exceeded without being an obvious protocol violation. | |
</t> | |
<t> | |
All these features - i.e., <x:ref>SETTINGS</x:ref> changes, small frames, header | |
compression - have legitimate uses. These features become a burden only when they are | |
used unnecessarily or to excess. | |
</t> | |
<t> | |
An endpoint that doesn't monitor this behavior exposes itself to a risk of denial of | |
service attack. Implementations SHOULD track the use of these features and set limits on | |
their use. An endpoint MAY treat activity that is suspicious as a <xref | |
target="ConnectionErrorHandler">connection error</xref> of type | |
<x:ref>ENHANCE_YOUR_CALM</x:ref>. | |
</t> | |
<section anchor="MaxHeaderBlock" title="Limits on Header Block Size"> | |
<t> | |
A large <xref target="HeaderBlock">header block</xref> can cause an implementation to | |
commit a large amount of state. Header fields that are critical for routing can appear | |
toward the end of a header block, which prevents streaming of header fields to their | |
ultimate destination. For this an other reasons, such as ensuring cache correctness, | |
means that an endpoint might need to buffer the entire header block. Since there is no | |
hard limit to the size of a header block, some endpoints could be forced commit a large | |
amount of available memory for header fields. | |
</t> | |
<t> | |
An endpoint can use the <x:ref>SETTINGS_MAX_HEADER_LIST_SIZE</x:ref> to advise peers of | |
limits that might apply on the size of header blocks. This setting is only advisory, so | |
endpoints MAY choose to send header blocks that exceed this limit and risk having the | |
request or response being treated as malformed. This setting specific to a connection, | |
so any request or response could encounter a hop with a lower, unknown limit. An | |
intermediary can attempt to avoid this problem by passing on values presented by | |
different peers, but they are not obligated to do so. | |
</t> | |
<t> | |
A server that receives a larger header block than it is willing to handle can send an | |
HTTP 431 (Request Header Fields Too Large) status code <xref target="RFC6585"/>. A | |
client can discard responses that it cannot process. The header block MUST be processed | |
to ensure a consistent connection state, unless the connection is closed. | |
</t> | |
</section> | |
</section> | |
<section title="Use of Compression"> | |
<t> | |
HTTP/2 enables greater use of compression for both header fields (<xref | |
target="HeaderBlock"/>) and entity bodies. Compression can allow an attacker to recover | |
secret data when it is compressed in the same context as data under attacker control. | |
</t> | |
<t> | |
There are demonstrable attacks on compression that exploit the characteristics of the web | |
(e.g., <xref target="BREACH"/>). The attacker induces multiple requests containing | |
varying plaintext, observing the length of the resulting ciphertext in each, which | |
reveals a shorter length when a guess about the secret is correct. | |
</t> | |
<t> | |
Implementations communicating on a secure channel MUST NOT compress content that includes | |
both confidential and attacker-controlled data unless separate compression dictionaries | |
are used for each source of data. Compression MUST NOT be used if the source of data | |
cannot be reliably determined. Generic stream compression, such as that provided by TLS | |
MUST NOT be used with HTTP/2 (<xref target="TLSFeatures"/>). | |
</t> | |
<t> | |
Further considerations regarding the compression of header fields are described in <xref | |
target="COMPRESSION"/>. | |
</t> | |
</section> | |
<section title="Use of Padding" anchor="padding"> | |
<t> | |
Padding within HTTP/2 is not intended as a replacement for general purpose padding, such | |
as might be provided by <xref target="TLS12">TLS</xref>. Redundant padding could even be | |
counterproductive. Correct application can depend on having specific knowledge of the | |
data that is being padded. | |
</t> | |
<t> | |
To mitigate attacks that rely on compression, disabling or limiting compression might be | |
preferable to padding as a countermeasure. | |
</t> | |
<t> | |
Padding can be used to obscure the exact size of frame content, and is provided to | |
mitigate specific attacks within HTTP. For example, attacks where compressed content | |
includes both attacker-controlled plaintext and secret data (see for example, <xref | |
target="BREACH"/>). | |
</t> | |
<t> | |
Use of padding can result in less protection than might seem immediately obvious. At | |
best, padding only makes it more difficult for an attacker to infer length information by | |
increasing the number of frames an attacker has to observe. Incorrectly implemented | |
padding schemes can be easily defeated. In particular, randomized padding with a | |
predictable distribution provides very little protection; similarly, padding payloads to a | |
fixed size exposes information as payload sizes cross the fixed size boundary, which could | |
be possible if an attacker can control plaintext. | |
</t> | |
<t> | |
Intermediaries SHOULD retain padding for <x:ref>DATA</x:ref> frames, but MAY drop padding | |
for <x:ref>HEADERS</x:ref> and <x:ref>PUSH_PROMISE</x:ref> frames. A valid reason for an | |
intermediary to change the amount of padding of frames is to improve the protections that | |
padding provides. | |
</t> | |
</section> | |
<section title="Privacy Considerations"> | |
<t> | |
Several characteristics of HTTP/2 provide an observer an opportunity to correlate actions | |
of a single client or server over time. This includes the value of settings, the manner | |
in which flow control windows are managed, the way priorities are allocated to streams, | |
timing of reactions to stimulus, and handling of any optional features. | |
</t> | |
<t> | |
As far as this creates observable differences in behavior, they could be used as a basis | |
for fingerprinting a specific client, as defined in <xref target="HTML5" x:fmt="of" | |
x:sec="1.8" x:rel="introduction.html#fingerprint"/>. | |
</t> | |
</section> | |
</section> | |
<section anchor="iana" title="IANA Considerations"> | |
<t> | |
A string for identifying HTTP/2 is entered into the "Application Layer Protocol Negotiation | |
(ALPN) Protocol IDs" registry established in <xref target="TLS-ALPN"/>. | |
</t> | |
<t> | |
This document establishes a registry for frame types, settings, and error codes. These new | |
registries are entered into a new "Hypertext Transfer Protocol (HTTP) 2 Parameters" section. | |
</t> | |
<t> | |
This document registers the <spanx style="verb">HTTP2-Settings</spanx> header field for | |
use in HTTP; and the 421 (Misdirected Request) status code. | |
</t> | |
<t> | |
This document registers the <spanx style="verb">PRI</spanx> method for use in HTTP, to avoid | |
collisions with the <xref target="ConnectionHeader">connection preface</xref>. | |
</t> | |
<section anchor="iana-alpn" title="Registration of HTTP/2 Identification Strings"> | |
<t> | |
This document creates two registrations for the identification of HTTP/2 in the | |
"Application Layer Protocol Negotiation (ALPN) Protocol IDs" registry established in <xref | |
target="TLS-ALPN"/>. | |
</t> | |
<t> | |
The "h2" string identifies HTTP/2 when used over TLS: | |
<list style="hanging"> | |
<t hangText="Protocol:">HTTP/2 over TLS</t> | |
<t hangText="Identification Sequence:">0x68 0x32 ("h2")</t> | |
<t hangText="Specification:">This document</t> | |
</list> | |
</t> | |
<t> | |
The "h2c" string identifies HTTP/2 when used over cleartext TCP: | |
<list style="hanging"> | |
<t hangText="Protocol:">HTTP/2 over TCP</t> | |
<t hangText="Identification Sequence:">0x68 0x32 0x63 ("h2c")</t> | |
<t hangText="Specification:">This document</t> | |
</list> | |
</t> | |
</section> | |
<section anchor="iana-frames" title="Frame Type Registry"> | |
<t> | |
This document establishes a registry for HTTP/2 frame type codes. The "HTTP/2 Frame | |
Type" registry manages an 8-bit space. The "HTTP/2 Frame Type" registry operates under | |
either of the <xref target="RFC5226">"IETF Review" or "IESG Approval" policies</xref> for | |
values between 0x00 and 0xef, with values between 0xf0 and 0xff being reserved for | |
experimental use. | |
</t> | |
<t> | |
New entries in this registry require the following information: | |
<list style="hanging"> | |
<t hangText="Frame Type:"> | |
A name or label for the frame type. | |
</t> | |
<t hangText="Code:"> | |
The 8-bit code assigned to the frame type. | |
</t> | |
<t hangText="Specification:"> | |
A reference to a specification that includes a description of the frame layout, | |
it's semantics and flags that the frame type uses, including any parts of the frame | |
that are conditionally present based on the value of flags. | |
</t> | |
</list> | |
</t> | |
<t> | |
The entries in the following table are registered by this document. | |
</t> | |
<texttable align="left" suppress-title="true"> | |
<ttcol>Frame Type</ttcol> | |
<ttcol>Code</ttcol> | |
<ttcol>Section</ttcol> | |
<c>DATA</c><c>0x0</c><c><xref target="DATA"/></c> | |
<c>HEADERS</c><c>0x1</c><c><xref target="HEADERS"/></c> | |
<c>PRIORITY</c><c>0x2</c><c><xref target="PRIORITY"/></c> | |
<c>RST_STREAM</c><c>0x3</c><c><xref target="RST_STREAM"/></c> | |
<c>SETTINGS</c><c>0x4</c><c><xref target="SETTINGS"/></c> | |
<c>PUSH_PROMISE</c><c>0x5</c><c><xref target="PUSH_PROMISE"/></c> | |
<c>PING</c><c>0x6</c><c><xref target="PING"/></c> | |
<c>GOAWAY</c><c>0x7</c><c><xref target="GOAWAY"/></c> | |
<c>WINDOW_UPDATE</c><c>0x8</c><c><xref target="WINDOW_UPDATE"/></c> | |
<c>CONTINUATION</c><c>0x9</c><c><xref target="CONTINUATION"/></c> | |
</texttable> | |
</section> | |
<section anchor="iana-settings" title="Settings Registry"> | |
<t> | |
This document establishes a registry for HTTP/2 settings. The "HTTP/2 Settings" registry | |
manages a 16-bit space. The "HTTP/2 Settings" registry operates under the <xref | |
target="RFC5226">"Expert Review" policy</xref> for values in the range from 0x0000 to | |
0xefff, with values between and 0xf000 and 0xffff being reserved for experimental use. | |
</t> | |
<t> | |
New registrations are advised to provide the following information: | |
<list style="hanging"> | |
<t hangText="Name:"> | |
A symbolic name for the setting. Specifying a setting name is optional. | |
</t> | |
<t hangText="Code:"> | |
The 16-bit code assigned to the setting. | |
</t> | |
<t hangText="Initial Value:"> | |
An initial value for the setting. | |
</t> | |
<t hangText="Specification:"> | |
An optional reference to a specification that describes the use of the setting. | |
</t> | |
</list> | |
</t> | |
<t> | |
An initial set of setting registrations can be found in <xref target="SettingValues"/>. | |
</t> | |
<texttable align="left" suppress-title="true"> | |
<ttcol>Name</ttcol> | |
<ttcol>Code</ttcol> | |
<ttcol>Initial Value</ttcol> | |
<ttcol>Specification</ttcol> | |
<c>HEADER_TABLE_SIZE</c> | |
<c>0x1</c><c>4096</c><c><xref target="SettingValues"/></c> | |
<c>ENABLE_PUSH</c> | |
<c>0x2</c><c>1</c><c><xref target="SettingValues"/></c> | |
<c>MAX_CONCURRENT_STREAMS</c> | |
<c>0x3</c><c>(infinite)</c><c><xref target="SettingValues"/></c> | |
<c>INITIAL_WINDOW_SIZE</c> | |
<c>0x4</c><c>65535</c><c><xref target="SettingValues"/></c> | |
<c>MAX_FRAME_SIZE</c> | |
<c>0x5</c><c>16384</c><c><xref target="SettingValues"/></c> | |
<c>MAX_HEADER_LIST_SIZE</c> | |
<c>0x6</c><c>(infinite)</c><c><xref target="SettingValues"/></c> | |
</texttable> | |
</section> | |
<section anchor="iana-errors" title="Error Code Registry"> | |
<t> | |
This document establishes a registry for HTTP/2 error codes. The "HTTP/2 Error Code" | |
registry manages a 32-bit space. The "HTTP/2 Error Code" registry operates under the | |
<xref target="RFC5226">"Expert Review" policy</xref>. | |
</t> | |
<t> | |
Registrations for error codes are required to include a description of the error code. An | |
expert reviewer is advised to examine new registrations for possible duplication with | |
existing error codes. Use of existing registrations is to be encouraged, but not | |
mandated. | |
</t> | |
<t> | |
New registrations are advised to provide the following information: | |
<list style="hanging"> | |
<t hangText="Name:"> | |
A name for the error code. Specifying an error code name is optional. | |
</t> | |
<t hangText="Code:"> | |
The 32-bit error code value. | |
</t> | |
<t hangText="Description:"> | |
A brief description of the error code semantics, longer if no detailed specification | |
is provided. | |
</t> | |
<t hangText="Specification:"> | |
An optional reference for a specification that defines the error code. | |
</t> | |
</list> | |
</t> | |
<t> | |
The entries in the following table are registered by this document. | |
</t> | |
<texttable align="left" suppress-title="true"> | |
<ttcol>Name</ttcol> | |
<ttcol>Code</ttcol> | |
<ttcol>Description</ttcol> | |
<ttcol>Specification</ttcol> | |
<c>NO_ERROR</c><c>0x0</c> | |
<c>Graceful shutdown</c> | |
<c><xref target="ErrorCodes"/></c> | |
<c>PROTOCOL_ERROR</c><c>0x1</c> | |
<c>Protocol error detected</c> | |
<c><xref target="ErrorCodes"/></c> | |
<c>INTERNAL_ERROR</c><c>0x2</c> | |
<c>Implementation fault</c> | |
<c><xref target="ErrorCodes"/></c> | |
<c>FLOW_CONTROL_ERROR</c><c>0x3</c> | |
<c>Flow control limits exceeded</c> | |
<c><xref target="ErrorCodes"/></c> | |
<c>SETTINGS_TIMEOUT</c><c>0x4</c> | |
<c>Settings not acknowledged</c> | |
<c><xref target="ErrorCodes"/></c> | |
<c>STREAM_CLOSED</c><c>0x5</c> | |
<c>Frame received for closed stream</c> | |
<c><xref target="ErrorCodes"/></c> | |
<c>FRAME_SIZE_ERROR</c><c>0x6</c> | |
<c>Frame size incorrect</c> | |
<c><xref target="ErrorCodes"/></c> | |
<c>REFUSED_STREAM</c><c>0x7</c> | |
<c>Stream not processed</c> | |
<c><xref target="ErrorCodes"/></c> | |
<c>CANCEL</c><c>0x8</c> | |
<c>Stream cancelled</c> | |
<c><xref target="ErrorCodes"/></c> | |
<c>COMPRESSION_ERROR</c><c>0x9</c> | |
<c>Compression state not updated</c> | |
<c><xref target="ErrorCodes"/></c> | |
<c>CONNECT_ERROR</c><c>0xa</c> | |
<c>TCP connection error for CONNECT method</c> | |
<c><xref target="ErrorCodes"/></c> | |
<c>ENHANCE_YOUR_CALM</c><c>0xb</c> | |
<c>Processing capacity exceeded</c> | |
<c><xref target="ErrorCodes"/></c> | |
<c>INADEQUATE_SECURITY</c><c>0xc</c> | |
<c>Negotiated TLS parameters not acceptable</c> | |
<c><xref target="ErrorCodes"/></c> | |
</texttable> | |
</section> | |
<section title="HTTP2-Settings Header Field Registration"> | |
<t> | |
This section registers the <spanx style="verb">HTTP2-Settings</spanx> header field in the | |
<xref target="BCP90">Permanent Message Header Field Registry</xref>. | |
<list style="hanging"> | |
<t hangText="Header field name:"> | |
HTTP2-Settings | |
</t> | |
<t hangText="Applicable protocol:"> | |
http | |
</t> | |
<t hangText="Status:"> | |
standard | |
</t> | |
<t hangText="Author/Change controller:"> | |
IETF | |
</t> | |
<t hangText="Specification document(s):"> | |
<xref target="Http2SettingsHeader"/> of this document | |
</t> | |
<t hangText="Related information:"> | |
This header field is only used by an HTTP/2 client for Upgrade-based negotiation. | |
</t> | |
</list> | |
</t> | |
</section> | |
<section title="PRI Method Registration"> | |
<t> | |
This section registers the <spanx style="verb">PRI</spanx> method in the HTTP Method | |
Registry (<xref target="RFC7231" x:fmt="," x:rel="#method.registry"/>). | |
<list style="hanging"> | |
<t hangText="Method Name:"> | |
PRI | |
</t> | |
<t hangText="Safe"> | |
No | |
</t> | |
<t hangText="Idempotent"> | |
No | |
</t> | |
<t hangText="Specification document(s)"> | |
<xref target="ConnectionHeader"/> of this document | |
</t> | |
<t hangText="Related information:"> | |
This method is never used by an actual client. This method will appear to be used | |
when an HTTP/1.1 server or intermediary attempts to parse an HTTP/2 connection | |
preface. | |
</t> | |
</list> | |
</t> | |
</section> | |
<section title="The 421 (Misdirected Request) HTTP Status Code" | |
anchor="iana-MisdirectedRequest"> | |
<t> | |
This document registers the 421 (Misdirected Request) HTTP Status code in the Hypertext | |
Transfer Protocol (HTTP) Status Code Registry (<xref target="RFC7231" x:fmt="," | |
x:rel="#status.code.registry"/>). | |
</t> | |
<t> | |
<list style="hanging"> | |
<t hangText="Status Code:"> | |
421 | |
</t> | |
<t hangText="Short Description:"> | |
Misdirected Request | |
</t> | |
<t hangText="Specification:"> | |
<xref target="MisdirectedRequest"/> of this document | |
</t> | |
</list> | |
</t> | |
</section> | |
</section> | |
<section title="Acknowledgements"> | |
<t> | |
This document includes substantial input from the following individuals: | |
<list style="symbols"> | |
<t> | |
Adam Langley, Wan-Teh Chang, Jim Morrison, Mark Nottingham, Alyssa Wilk, Costin | |
Manolache, William Chan, Vitaliy Lvin, Joe Chan, Adam Barth, Ryan Hamilton, Gavin | |
Peters, Kent Alstad, Kevin Lindsay, Paul Amer, Fan Yang, Jonathan Leighton (SPDY | |
contributors). | |
</t> | |
<t> | |
Gabriel Montenegro and Willy Tarreau (Upgrade mechanism). | |
</t> | |
<t> | |
William Chan, Salvatore Loreto, Osama Mazahir, Gabriel Montenegro, Jitu Padhye, Roberto | |
Peon, Rob Trace (Flow control). | |
</t> | |
<t> | |
Mike Bishop (Extensibility). | |
</t> | |
<t> | |
Mark Nottingham, Julian Reschke, James Snell, Jeff Pinner, Mike Bishop, Herve Ruellan | |
(Substantial editorial contributions). | |
</t> | |
<t> | |
Kari Hurtta, Tatsuhiro Tsujikawa, Greg Wilkins, Poul-Henning Kamp. | |
</t> | |
<t> | |
Alexey Melnikov was an editor of this document during 2013. | |
</t> | |
<t> | |
A substantial proportion of Martin's contribution was supported by Microsoft during his | |
employment there. | |
</t> | |
</list> | |
</t> | |
</section> | |
</middle> | |
<back> | |
<references title="Normative References"> | |
<reference anchor="COMPRESSION"> | |
<front> | |
<title>HPACK - Header Compression for HTTP/2</title> | |
<author initials="H." surname="Ruellan" fullname="Herve Ruellan"/> | |
<author initials="R." surname="Peon" fullname="Roberto Peon"/> | |
<date month="July" year="2014" /> | |
</front> | |
<seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-header-compression-09" /> | |
<x:source href="refs/draft-ietf-httpbis-header-compression-09.xml"/> | |
</reference> | |
<reference anchor="TCP"> | |
<front> | |
<title abbrev="Transmission Control Protocol"> | |
Transmission Control Protocol | |
</title> | |
<author initials="J." surname="Postel" fullname="Jon Postel"> | |
<organization>University of Southern California (USC)/Information Sciences | |
Institute</organization> | |
</author> | |
<date year="1981" month="September" /> | |
</front> | |
<seriesInfo name="STD" value="7" /> | |
<seriesInfo name="RFC" value="793" /> | |
</reference> | |
<reference anchor="RFC2119"> | |
<front> | |
<title> | |
Key words for use in RFCs to Indicate Requirement Levels | |
</title> | |
<author initials="S." surname="Bradner" fullname="Scott Bradner"> | |
<organization>Harvard University</organization> | |
<address><email>sob@harvard.edu</email></address> | |
</author> | |
<date month="March" year="1997"/> | |
</front> | |
<seriesInfo name="BCP" value="14"/> | |
<seriesInfo name="RFC" value="2119"/> | |
</reference> | |
<reference anchor="RFC2818"> | |
<front> | |
<title> | |
HTTP Over TLS | |
</title> | |
<author initials="E." surname="Rescorla" fullname="Eric Rescorla"/> | |
<date month="May" year="2000"/> | |
</front> | |
<seriesInfo name="RFC" value="2818"/> | |
</reference> | |
<reference anchor="RFC3986"> | |
<front> | |
<title abbrev="URI Generic Syntax">Uniform Resource Identifier (URI): Generic | |
Syntax</title> | |
<author initials="T." surname="Berners-Lee" fullname="Tim Berners-Lee"></author> | |
<author initials="R." surname="Fielding" fullname="Roy T. Fielding"></author> | |
<author initials="L." surname="Masinter" fullname="Larry Masinter"></author> | |
<date year="2005" month="January" /> | |
</front> | |
<seriesInfo name="STD" value="66" /> | |
<seriesInfo name="RFC" value="3986" /> | |
</reference> | |
<reference anchor="RFC4648"> | |
<front> | |
<title>The Base16, Base32, and Base64 Data Encodings</title> | |
<author fullname="S. Josefsson" initials="S." surname="Josefsson"/> | |
<date year="2006" month="October"/> | |
</front> | |
<seriesInfo value="4648" name="RFC"/> | |
</reference> | |
<reference anchor="RFC5226"> | |
<front> | |
<title>Guidelines for Writing an IANA Considerations Section in RFCs</title> | |
<author initials="T." surname="Narten" fullname="T. Narten"/> | |
<author initials="H." surname="Alvestrand" fullname="H. Alvestrand"/> | |
<date year="2008" month="May" /> | |
</front> | |
<seriesInfo name="BCP" value="26" /> | |
<seriesInfo name="RFC" value="5226" /> | |
</reference> | |
<reference anchor="RFC5234"> | |
<front> | |
<title>Augmented BNF for Syntax Specifications: ABNF</title> | |
<author initials="D." surname="Crocker" fullname="D. Crocker"/> | |
<author initials="P." surname="Overell" fullname="P. Overell"/> | |
<date year="2008" month="January" /> | |
</front> | |
<seriesInfo name="STD" value="68" /> | |
<seriesInfo name="RFC" value="5234" /> | |
</reference> | |
<reference anchor="TLS12"> | |
<front> | |
<title>The Transport Layer Security (TLS) Protocol Version 1.2</title> | |
<author initials="T." surname="Dierks" fullname="Tim Dierks"/> | |
<author initials="E." surname="Rescorla" fullname="Eric Rescorla"/> | |
<date year="2008" month="August" /> | |
</front> | |
<seriesInfo name="RFC" value="5246" /> | |
</reference> | |
<reference anchor="TLS-EXT"> | |
<front> | |
<title> | |
Transport Layer Security (TLS) Extensions: Extension Definitions | |
</title> | |
<author initials="D." surname="Eastlake" fullname="D. Eastlake"/> | |
<date year="2011" month="January"/> | |
</front> | |
<seriesInfo name="RFC" value="6066"/> | |
</reference> | |
<reference anchor="TLS-ALPN"> | |
<front> | |
<title>Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension</title> | |
<author initials="S." surname="Friedl" fullname="Stephan Friedl"></author> | |
<author initials="A." surname="Popov" fullname="Andrei Popov"></author> | |
<author initials="A." surname="Langley" fullname="Adam Langley"></author> | |
<author initials="E." surname="Stephan" fullname="Emile Stephan"></author> | |
<date month="July" year="2014" /> | |
</front> | |
<seriesInfo name="RFC" value="7301" /> | |
</reference> | |
<reference anchor="TLS-ECDHE"> | |
<front> | |
<title> | |
TLS Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois | |
Counter Mode (GCM) | |
</title> | |
<author initials="E." surname="Rescorla" fullname="E. Rescorla"/> | |
<date year="2008" month="August" /> | |
</front> | |
<seriesInfo name="RFC" value="5289" /> | |
</reference> | |
<reference anchor="FIPS186"> | |
<front> | |
<title> | |
Digital Signature Standard (DSS) | |
</title> | |
<author><organization>NIST</organization></author> | |
<date year="2013" month="July" /> | |
</front> | |
<seriesInfo name="FIPS" value="PUB 186-4" /> | |
</reference> | |
<reference anchor="RFC7230"> | |
<front> | |
<title> | |
Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing</title> | |
<author fullname="Roy T. Fielding" initials="R." role="editor" surname="Fielding"> | |
<organization abbrev="Adobe">Adobe Systems Incorporated</organization> | |
<address><email>fielding@gbiv.com</email></address> | |
</author> | |
<author fullname="Julian F. Reschke" initials="J. F." role="editor" surname="Reschke"> | |
<organization abbrev="greenbytes">greenbytes GmbH</organization> | |
<address><email>julian.reschke@greenbytes.de</email></address> | |
</author> | |
<date month="June" year="2014" /> | |
</front> | |
<seriesInfo name="RFC" value="7230" /> | |
<x:source href="refs/rfc7230.xml" | |
basename="https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7230"/> | |
</reference> | |
<reference anchor="RFC7231"> | |
<front> | |
<title> | |
Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content</title> | |
<author fullname="Roy T. Fielding" initials="R." role="editor" surname="Fielding"> | |
<organization abbrev="Adobe">Adobe Systems Incorporated</organization> | |
<address><email>fielding@gbiv.com</email></address> | |
</author> | |
<author fullname="Julian F. Reschke" initials="J. F." role="editor" surname="Reschke"> | |
<organization abbrev="greenbytes">greenbytes GmbH</organization> | |
<address><email>julian.reschke@greenbytes.de</email></address> | |
</author> | |
<date month="June" year="2014" /> | |
</front> | |
<seriesInfo name="RFC" value="7231" /> | |
<x:source href="refs/rfc7231.xml" | |
basename="https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7231"/> | |
</reference> | |
<reference anchor="RFC7232"> | |
<front> | |
<title>Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests</title> | |
<author fullname="Roy T. Fielding" initials="R." role="editor" surname="Fielding"> | |
<organization abbrev="Adobe">Adobe Systems Incorporated</organization> | |
<address><email>fielding@gbiv.com</email></address> | |
</author> | |
<author fullname="Julian F. Reschke" initials="J. F." role="editor" surname="Reschke"> | |
<organization abbrev="greenbytes">greenbytes GmbH</organization> | |
<address><email>julian.reschke@greenbytes.de</email></address> | |
</author> | |
<date month="June" year="2014" /> | |
</front> | |
<seriesInfo name="RFC" value="7232" /> | |
</reference> | |
<reference anchor="RFC7233"> | |
<front> | |
<title>Hypertext Transfer Protocol (HTTP/1.1): Range Requests</title> | |
<author initials="R." surname="Fielding" fullname="Roy T. Fielding" role="editor"> | |
<organization abbrev="Adobe">Adobe Systems Incorporated</organization> | |
<address><email>fielding@gbiv.com</email></address> | |
</author> | |
<author initials="Y." surname="Lafon" fullname="Yves Lafon" role="editor"> | |
<organization abbrev="W3C">World Wide Web Consortium</organization> | |
<address><email>ylafon@w3.org</email></address> | |
</author> | |
<author initials="J. F." surname="Reschke" fullname="Julian F. Reschke" role="editor"> | |
<organization abbrev="greenbytes">greenbytes GmbH</organization> | |
<address><email>julian.reschke@greenbytes.de</email></address> | |
</author> | |
<date month="June" year="2014" /> | |
</front> | |
<seriesInfo name="RFC" value="7233" /> | |
</reference> | |
<reference anchor="RFC7234"> | |
<front> | |
<title>Hypertext Transfer Protocol (HTTP/1.1): Caching</title> | |
<author initials="R." surname="Fielding" fullname="Roy T. Fielding" role="editor"> | |
<organization abbrev="Adobe">Adobe Systems Incorporated</organization> | |
<address><email>fielding@gbiv.com</email></address> | |
</author> | |
<author fullname="Mark Nottingham" initials="M." role="editor" surname="Nottingham"> | |
<organization>Akamai</organization> | |
<address><email>mnot@mnot.net</email></address> | |
</author> | |
<author initials="J. F." surname="Reschke" fullname="Julian F. Reschke" role="editor"> | |
<organization abbrev="greenbytes">greenbytes GmbH</organization> | |
<address><email>julian.reschke@greenbytes.de</email></address> | |
</author> | |
<date month="June" year="2014" /> | |
</front> | |
<seriesInfo name="RFC" value="7234"/> | |
<x:source href="refs/rfc7234.xml" | |
basename="https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7234"/> | |
</reference> | |
<reference anchor="RFC7235"> | |
<front> | |
<title>Hypertext Transfer Protocol (HTTP/1.1): Authentication</title> | |
<author initials="R." surname="Fielding" fullname="Roy T. Fielding" role="editor"> | |
<organization abbrev="Adobe">Adobe Systems Incorporated</organization> | |
<address><email>fielding@gbiv.com</email></address> | |
</author> | |
<author initials="J. F." surname="Reschke" fullname="Julian F. Reschke" role="editor"> | |
<organization abbrev="greenbytes">greenbytes GmbH</organization> | |
<address><email>julian.reschke@greenbytes.de</email></address> | |
</author> | |
<date month="June" year="2014" /> | |
</front> | |
<seriesInfo name="RFC" value="7235"/> | |
<x:source href="refs/rfc7235.xml" | |
basename="https://svn.tools.ietf.org/svn/wg/httpbis/specs/rfc7235"/> | |
</reference> | |
<reference anchor="COOKIE"> | |
<front> | |
<title>HTTP State Management Mechanism</title> | |
<author initials="A." surname="Barth" fullname="A. Barth"/> | |
<date year="2011" month="April" /> | |
</front> | |
<seriesInfo name="RFC" value="6265" /> | |
</reference> | |
</references> | |
<references title="Informative References"> | |
<reference anchor="RFC1323"> | |
<front> | |
<title> | |
TCP Extensions for High Performance | |
</title> | |
<author initials="V." surname="Jacobson" fullname="Van Jacobson"></author> | |
<author initials="B." surname="Braden" fullname="Bob Braden"></author> | |
<author initials="D." surname="Borman" fullname="Dave Borman"></author> | |
<date year="1992" month="May" /> | |
</front> | |
<seriesInfo name="RFC" value="1323" /> | |
</reference> | |
<reference anchor="RFC3749"> | |
<front> | |
<title>Transport Layer Security Protocol Compression Methods</title> | |
<author initials="S." surname="Hollenbeck" fullname="S. Hollenbeck"/> | |
<date year="2004" month="May" /> | |
</front> | |
<seriesInfo name="RFC" value="3749" /> | |
</reference> | |
<reference anchor="RFC6585"> | |
<front> | |
<title>Additional HTTP Status Codes</title> | |
<author initials="M." surname="Nottingham" fullname="Mark Nottingham"/> | |
<author initials="R." surname="Fielding" fullname="Roy Fielding"/> | |
<date year="2012" month="April" /> | |
</front> | |
<seriesInfo name="RFC" value="6585" /> | |
</reference> | |
<reference anchor="RFC4492"> | |
<front> | |
<title> | |
Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS) | |
</title> | |
<author initials="S." surname="Blake-Wilson" fullname="S. Blake-Wilson"/> | |
<author initials="N." surname="Bolyard" fullname="N. Bolyard"/> | |
<author initials="V." surname="Gupta" fullname="V. Gupta"/> | |
<author initials="C." surname="Hawk" fullname="C. Hawk"/> | |
<author initials="B." surname="Moeller" fullname="B. Moeller"/> | |
<date year="2006" month="May" /> | |
</front> | |
<seriesInfo name="RFC" value="4492" /> | |
</reference> | |
<reference anchor="RFC5288"> | |
<front> | |
<title> | |
AES Galois Counter Mode (GCM) Cipher Suites for TLS | |
</title> | |
<author initials="J." surname="Salowey" fullname="J. Salowey"/> | |
<author initials="A." surname="Choudhury" fullname="A. Choudhury"/> | |
<author initials="D." surname="McGrew" fullname="D. McGrew"/> | |
<date year="2008" month="August" /> | |
</front> | |
<seriesInfo name="RFC" value="5288" /> | |
</reference> | |
<reference anchor='HTML5' | |
target='http://www.w3.org/TR/2014/CR-html5-20140731/'> | |
<front> | |
<title>HTML5</title> | |
<author fullname='Robin Berjon' surname='Berjon' initials='R.'/> | |
<author fullname='Steve Faulkner' surname='Faulkner' initials='S.'/> | |
<author fullname='Travis Leithead' surname='Leithead' initials='T.'/> | |
<author fullname='Erika Doyle Navara' surname='Doyle Navara' initials='E.'/> | |
<author fullname='Edward O'Connor' surname='O'Connor' initials='E.'/> | |
<author fullname='Silvia Pfeiffer' surname='Pfeiffer' initials='S.'/> | |
<date year='2014' month='July' day='31'/> | |
</front> | |
<seriesInfo name='W3C Candidate Recommendation' value='CR-html5-20140731'/> | |
<annotation> | |
Latest version available at | |
<eref target='http://www.w3.org/TR/html5/'/>. | |
</annotation> | |
</reference> | |
<reference anchor="TALKING" target="http://w2spconf.com/2011/papers/websocket.pdf"> | |
<front> | |
<title> | |
Talking to Yourself for Fun and Profit | |
</title> | |
<author initials="L-S." surname="Huang"/> | |
<author initials="E." surname="Chen"/> | |
<author initials="A." surname="Barth"/> | |
<author initials="E." surname="Rescorla"/> | |
<author initials="C." surname="Jackson"/> | |
<date year="2011" /> | |
</front> | |
</reference> | |
<reference anchor="BREACH" | |
target="http://breachattack.com/resources/BREACH%20-%20SSL,%20gone%20in%2030%20seconds.pdf"> | |
<front> | |
<title> | |
BREACH: Reviving the CRIME Attack | |
</title> | |
<author initials="Y." surname="Gluck"/> | |
<author initials="N." surname="Harris"/> | |
<author initials="A." surname="Prado"/> | |
<date year="2013" month="July" day="12"/> | |
</front> | |
</reference> | |
<reference anchor="BCP90"> | |
<front> | |
<title>Registration Procedures for Message Header Fields</title> | |
<author initials="G." surname="Klyne" fullname="G. Klyne"> | |
<organization>Nine by Nine</organization> | |
<address><email>GK-IETF@ninebynine.org</email></address> | |
</author> | |
<author initials="M." surname="Nottingham" fullname="M. Nottingham"> | |
<organization>BEA Systems</organization> | |
<address><email>mnot@pobox.com</email></address> | |
</author> | |
<author initials="J." surname="Mogul" fullname="J. Mogul"> | |
<organization>HP Labs</organization> | |
<address><email>JeffMogul@acm.org</email></address> | |
</author> | |
<date year="2004" month="September" /> | |
</front> | |
<seriesInfo name="BCP" value="90" /> | |
<seriesInfo name="RFC" value="3864" /> | |
</reference> | |
<reference anchor="TLSBCP"> | |
<front> | |
<title>Recommendations for Secure Use of TLS and DTLS</title> | |
<author initials="Y" surname="Sheffer" fullname="Yaron Sheffer"> | |
<organization /> | |
</author> | |
<author initials="R" surname="Holz" fullname="Ralph Holz"> | |
<organization /> | |
</author> | |
<author initials="P" surname="Saint-Andre" fullname="Peter Saint-Andre"> | |
<organization /> | |
</author> | |
<date month="June" day="23" year="2014" /> | |
</front> | |
<seriesInfo name="Internet-Draft" value="draft-ietf-uta-tls-bcp-01" /> | |
</reference> | |
<reference anchor="ALT-SVC"> | |
<front> | |
<title> | |
HTTP Alternative Services | |
</title> | |
<author initials="M." surname="Nottingham" fullname="Mark Nottingham"> | |
<organization>Akamai</organization> | |
</author> | |
<author initials="P." surname="McManus" fullname="Patrick McManus"> | |
<organization>Mozilla</organization> | |
</author> | |
<author initials="J." surname="Reschke" fullname="Julian Reschke"> | |
<organization>greenbytes</organization> | |
</author> | |
<date year="2014" month="April"/> | |
</front> | |
<seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-alt-svc-02"/> | |
<x:source href="refs/draft-ietf-httpbis-alt-svc-02.xml"/> | |
</reference> | |
</references> | |
<section title="Change Log" anchor="change.log"> | |
<t> | |
This section is to be removed by RFC Editor before publication. | |
</t> | |
<section title="Since draft-ietf-httpbis-http2-14" anchor="changes.since.draft-ietf-httpbis-http2-14"> | |
<t> | |
Renamed Not Authoritative status code to Misdirected Request. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-13" anchor="changes.since.draft-ietf-httpbis-http2-13"> | |
<t> | |
Pseudo-header fields are now required to appear strictly before regular ones. | |
</t> | |
<t> | |
Restored 1xx series status codes, except 101. | |
</t> | |
<t> | |
Changed frame length field 24-bits. Expanded frame header to 9 octets. Added a setting | |
to limit the damage. | |
</t> | |
<t> | |
Added a setting to advise peers of header set size limits. | |
</t> | |
<t> | |
Removed segments. | |
</t> | |
<t> | |
Made non-semantic-bearing <x:ref>HEADERS</x:ref> frames illegal in the HTTP mapping. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-12" anchor="changes.since.draft-ietf-httpbis-http2-12"> | |
<t> | |
Restored extensibility options. | |
</t> | |
<t> | |
Restricting TLS cipher suites to AEAD only. | |
</t> | |
<t> | |
Removing Content-Encoding requirements. | |
</t> | |
<t> | |
Permitting the use of <x:ref>PRIORITY</x:ref> after stream close. | |
</t> | |
<t> | |
Removed ALTSVC frame. | |
</t> | |
<t> | |
Removed BLOCKED frame. | |
</t> | |
<t> | |
Reducing the maximum padding size to 256 octets; removing padding from | |
<x:ref>CONTINUATION</x:ref> frames. | |
</t> | |
<t> | |
Removed per-frame GZIP compression. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-11" anchor="changes.since.draft-ietf-httpbis-http2-11"> | |
<t> | |
Added BLOCKED frame (at risk). | |
</t> | |
<t> | |
Simplified priority scheme. | |
</t> | |
<t> | |
Added <x:ref>DATA</x:ref> per-frame GZIP compression. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-10" anchor="changes.since.draft-ietf-httpbis-http2-10"> | |
<t> | |
Changed "connection header" to "connection preface" to avoid confusion. | |
</t> | |
<t> | |
Added dependency-based stream prioritization. | |
</t> | |
<t> | |
Added "h2c" identifier to distinguish between cleartext and secured HTTP/2. | |
</t> | |
<t> | |
Adding missing padding to <x:ref>PUSH_PROMISE</x:ref>. | |
</t> | |
<t> | |
Integrate ALTSVC frame and supporting text. | |
</t> | |
<t> | |
Dropping requirement on "deflate" Content-Encoding. | |
</t> | |
<t> | |
Improving security considerations around use of compression. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-09" anchor="changes.since.draft-ietf-httpbis-http2-09"> | |
<t> | |
Adding padding for data frames. | |
</t> | |
<t> | |
Renumbering frame types, error codes, and settings. | |
</t> | |
<t> | |
Adding INADEQUATE_SECURITY error code. | |
</t> | |
<t> | |
Updating TLS usage requirements to 1.2; forbidding TLS compression. | |
</t> | |
<t> | |
Removing extensibility for frames and settings. | |
</t> | |
<t> | |
Changing setting identifier size. | |
</t> | |
<t> | |
Removing the ability to disable flow control. | |
</t> | |
<t> | |
Changing the protocol identification token to "h2". | |
</t> | |
<t> | |
Changing the use of :authority to make it optional and to allow userinfo in non-HTTP | |
cases. | |
</t> | |
<t> | |
Allowing split on 0x0 for Cookie. | |
</t> | |
<t> | |
Reserved PRI method in HTTP/1.1 to avoid possible future collisions. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-08" anchor="changes.since.draft-ietf-httpbis-http2-08"> | |
<t> | |
Added cookie crumbling for more efficient header compression. | |
</t> | |
<t> | |
Added header field ordering with the value-concatenation mechanism. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-07" anchor="changes.since.draft-ietf-httpbis-http2-07"> | |
<t> | |
Marked draft for implementation. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-06" anchor="changes.since.draft-ietf-httpbis-http2-06"> | |
<t> | |
Adding definition for CONNECT method. | |
</t> | |
<t> | |
Constraining the use of push to safe, cacheable methods with no request body. | |
</t> | |
<t> | |
Changing from :host to :authority to remove any potential confusion. | |
</t> | |
<t> | |
Adding setting for header compression table size. | |
</t> | |
<t> | |
Adding settings acknowledgement. | |
</t> | |
<t> | |
Removing unnecessary and potentially problematic flags from CONTINUATION. | |
</t> | |
<t> | |
Added denial of service considerations. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-05" anchor="changes.since.draft-ietf-httpbis-http2-05"> | |
<t> | |
Marking the draft ready for implementation. | |
</t> | |
<t> | |
Renumbering END_PUSH_PROMISE flag. | |
</t> | |
<t> | |
Editorial clarifications and changes. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-04" anchor="changes.since.draft-ietf-httpbis-http2-04"> | |
<t> | |
Added CONTINUATION frame for HEADERS and PUSH_PROMISE. | |
</t> | |
<t> | |
PUSH_PROMISE is no longer implicitly prohibited if SETTINGS_MAX_CONCURRENT_STREAMS is | |
zero. | |
</t> | |
<t> | |
Push expanded to allow all safe methods without a request body. | |
</t> | |
<t> | |
Clarified the use of HTTP header fields in requests and responses. Prohibited HTTP/1.1 | |
hop-by-hop header fields. | |
</t> | |
<t> | |
Requiring that intermediaries not forward requests with missing or illegal routing | |
:-headers. | |
</t> | |
<t> | |
Clarified requirements around handling different frames after stream close, stream reset | |
and <x:ref>GOAWAY</x:ref>. | |
</t> | |
<t> | |
Added more specific prohibitions for sending of different frame types in various stream | |
states. | |
</t> | |
<t> | |
Making the last received setting value the effective value. | |
</t> | |
<t> | |
Clarified requirements on TLS version, extension and ciphers. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-03" anchor="changes.since.draft-ietf-httpbis-http2-03"> | |
<t> | |
Committed major restructuring atrocities. | |
</t> | |
<t> | |
Added reference to first header compression draft. | |
</t> | |
<t> | |
Added more formal description of frame lifecycle. | |
</t> | |
<t> | |
Moved END_STREAM (renamed from FINAL) back to <x:ref>HEADERS</x:ref>/<x:ref>DATA</x:ref>. | |
</t> | |
<t> | |
Removed HEADERS+PRIORITY, added optional priority to <x:ref>HEADERS</x:ref> frame. | |
</t> | |
<t> | |
Added <x:ref>PRIORITY</x:ref> frame. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-02" anchor="changes.since.draft-ietf-httpbis-http2-02"> | |
<t> | |
Added continuations to frames carrying header blocks. | |
</t> | |
<t> | |
Replaced use of "session" with "connection" to avoid confusion with other HTTP stateful | |
concepts, like cookies. | |
</t> | |
<t> | |
Removed "message". | |
</t> | |
<t> | |
Switched to TLS ALPN from NPN. | |
</t> | |
<t> | |
Editorial changes. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-01" anchor="changes.since.draft-ietf-httpbis-http2-01"> | |
<t> | |
Added IANA considerations section for frame types, error codes and settings. | |
</t> | |
<t> | |
Removed data frame compression. | |
</t> | |
<t> | |
Added <x:ref>PUSH_PROMISE</x:ref>. | |
</t> | |
<t> | |
Added globally applicable flags to framing. | |
</t> | |
<t> | |
Removed zlib-based header compression mechanism. | |
</t> | |
<t> | |
Updated references. | |
</t> | |
<t> | |
Clarified stream identifier reuse. | |
</t> | |
<t> | |
Removed CREDENTIALS frame and associated mechanisms. | |
</t> | |
<t> | |
Added advice against naive implementation of flow control. | |
</t> | |
<t> | |
Added session header section. | |
</t> | |
<t> | |
Restructured frame header. Removed distinction between data and control frames. | |
</t> | |
<t> | |
Altered flow control properties to include session-level limits. | |
</t> | |
<t> | |
Added note on cacheability of pushed resources and multiple tenant servers. | |
</t> | |
<t> | |
Changed protocol label form based on discussions. | |
</t> | |
</section> | |
<section title="Since draft-ietf-httpbis-http2-00" anchor="changes.since.draft-ietf-httpbis-http2-00"> | |
<t> | |
Changed title throughout. | |
</t> | |
<t> | |
Removed section on Incompatibilities with SPDY draft#2. | |
</t> | |
<t> | |
Changed <x:ref>INTERNAL_ERROR</x:ref> on <x:ref>GOAWAY</x:ref> to have a value of 2 <eref | |
target="https://groups.google.com/forum/?fromgroups#!topic/spdy-dev/cfUef2gL3iU"/>. | |
</t> | |
<t> | |
Replaced abstract and introduction. | |
</t> | |
<t> | |
Added section on starting HTTP/2.0, including upgrade mechanism. | |
</t> | |
<t> | |
Removed unused references. | |
</t> | |
<t> | |
Added <xref target="fc-principles">flow control principles</xref> based on <eref | |
target="https://tools.ietf.org/html/draft-montenegro-httpbis-http2-fc-principles-01"/>. | |
</t> | |
</section> | |
<section title="Since draft-mbelshe-httpbis-spdy-00" anchor="changes.since.draft-mbelshe-httpbis-spdy-00"> | |
<t> | |
Adopted as base for draft-ietf-httpbis-http2. | |
</t> | |
<t> | |
Updated authors/editors list. | |
</t> | |
<t> | |
Added status note. | |
</t> | |
</section> | |
</section> | |
</back> | |
</rfc> | |
<!-- | |
vim:et:tw=100:sw=2: | |
--> |