mirror of
https://github.com/Luzifer/vault-openvpn.git
synced 2024-12-29 08:11:20 +00:00
5022 lines
252 KiB
XML
5022 lines
252 KiB
XML
|
<?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 maintainance.
|
||
|
</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:
|
||
|
-->
|