Browse Source

spec coverage report

Blake Mizerany 11 years ago
parent
commit
1c864e5f85
2 changed files with 5279 additions and 0 deletions
  1. 5021 0
      testdata/draft-ietf-httpbis-http2.xml
  2. 258 0
      z_spec_test.go

+ 5021 - 0
testdata/draft-ietf-httpbis-http2.xml

@@ -0,0 +1,5021 @@
+<?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&amp;body=&lt;{ref}&gt;:"/>
+  <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 &quot;http&quot; 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=&#34;request&#34;" 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=&#34;response&#34;" 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=&#34;response&#34;" 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 &quot;https&quot; 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&apos;Connor' surname='O&apos;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:
+  -->

+ 258 - 0
z_spec_test.go

@@ -0,0 +1,258 @@
+// Copyright 2014 The Go Authors.
+// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
+// Licensed under the same terms as Go itself:
+// https://code.google.com/p/go/source/browse/LICENSE
+
+package http2
+
+import (
+	"encoding/xml"
+	"fmt"
+	"io"
+	"os"
+	"reflect"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+// The global map of sentence coverage for the http2 spec.
+var defaultSpecCoverage specCoverage
+
+func init() {
+	f, err := os.Open("testdata/draft-ietf-httpbis-http2.xml")
+	if err != nil {
+		panic(err)
+	}
+	defaultSpecCoverage = readSpecCov(f)
+}
+
+// specCover marks all sentences for section sec in defaultSpecCoverage. Sentences not
+// "covered" will be included report outputed by TestSpecCoverage.
+func specCover(sec, sentences string) {
+	defaultSpecCoverage.cover(sec, sentences)
+}
+
+type specPart struct {
+	section  string
+	sentence string
+}
+
+func (ss specPart) Less(oo specPart) bool {
+	atoi := func(s string) int {
+		n, err := strconv.Atoi(s)
+		if err != nil {
+			panic(err)
+		}
+		return n
+	}
+	a := strings.Split(ss.section, ".")
+	b := strings.Split(oo.section, ".")
+	for i := 0; i < len(a); i++ {
+		if i >= len(b) {
+			return false
+		}
+		x, y := atoi(a[i]), atoi(b[i])
+		if x < y {
+			return true
+		}
+	}
+	return false
+}
+
+type bySpecSection []specPart
+
+func (a bySpecSection) Len() int           { return len(a) }
+func (a bySpecSection) Less(i, j int) bool { return a[i].Less(a[j]) }
+func (a bySpecSection) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+
+type specCoverage map[specPart]bool
+
+func readSection(sc specCoverage, d *xml.Decoder, sec []int) {
+	sub := 0
+	for {
+		tk, err := d.Token()
+		if err != nil {
+			if err == io.EOF {
+				return
+			}
+			panic(err)
+		}
+		switch v := tk.(type) {
+		case xml.StartElement:
+			if v.Name.Local == "section" {
+				sub++
+				readSection(sc, d, append(sec, sub))
+			}
+		case xml.CharData:
+			if len(sec) == 0 {
+				break
+			}
+			ssec := fmt.Sprintf("%d", sec[0])
+			for _, n := range sec[1:] {
+				ssec = fmt.Sprintf("%s.%d", ssec, n)
+			}
+			sc.addSentences(ssec, string(v))
+		case xml.EndElement:
+			if v.Name.Local == "section" {
+				return
+			}
+		}
+	}
+
+}
+
+func readSpecCov(r io.Reader) specCoverage {
+	d := xml.NewDecoder(r)
+	sc := specCoverage{}
+	readSection(sc, d, nil)
+	return sc
+}
+
+func (sc specCoverage) addSentences(sec string, sentence string) {
+	for _, s := range parseSentences(sentence) {
+		sc[specPart{sec, s}] = false
+	}
+}
+
+func (sc specCoverage) cover(sec string, sentence string) {
+	for _, s := range parseSentences(sentence) {
+		p := specPart{sec, s}
+		if _, ok := sc[p]; !ok {
+			panic(fmt.Sprintf("Not found in spec: %q, %q", sec, s))
+		}
+		sc[specPart{sec, s}] = true
+	}
+
+}
+
+func parseSentences(sens string) []string {
+	sens = strings.TrimSpace(sens)
+	if sens == "" {
+		return nil
+	}
+	rx := regexp.MustCompile("[\t\n\r]")
+	ss := strings.Split(rx.ReplaceAllString(sens, " "), ". ")
+	for i, s := range ss {
+		s = strings.TrimSpace(s)
+		if !strings.HasSuffix(s, ".") {
+			s += "."
+		}
+		ss[i] = s
+	}
+	return ss
+}
+
+func Test_Z_Spec_ParseSentences(t *testing.T) {
+	tests := []struct {
+		ss   string
+		want []string
+	}{
+		{"Sentence 1. Sentence 2.",
+			[]string{
+				"Sentence 1.",
+				"Sentence 2.",
+			}},
+		{"Sentence 1.  \nSentence 2.\tSentence 3.",
+			[]string{
+				"Sentence 1.",
+				"Sentence 2.",
+				"Sentence 3.",
+			}},
+	}
+
+	for i, tt := range tests {
+		got := parseSentences(tt.ss)
+		if !reflect.DeepEqual(got, tt.want) {
+			t.Errorf("%d: got = %q, want %q", i, got, tt.want)
+		}
+	}
+}
+
+func Test_Z_BuildCoverageTable(t *testing.T) {
+	testdata := `
+<rfc>
+  <middle>
+    <section anchor="intro" title="Introduction">
+      <t>Foo.</t>
+      <t><t>Sentence 1.
+      Sentence 2
+   .	Sentence 3.</t></t>
+    </section>
+    <section anchor="bar" title="Introduction">
+      <t>Bar.</t>
+	<section anchor="bar" title="Introduction">
+	  <t>Baz.</t>
+	</section>
+    </section>
+  </middle>
+</rfc>`
+	got := readSpecCov(strings.NewReader(testdata))
+	want := specCoverage{
+		specPart{"1", "Foo."}:        false,
+		specPart{"1", "Sentence 1."}: false,
+		specPart{"1", "Sentence 2."}: false,
+		specPart{"1", "Sentence 3."}: false,
+		specPart{"2", "Bar."}:        false,
+		specPart{"2.1", "Baz."}:      false,
+	}
+
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("got = %+v, want %+v", got, want)
+	}
+}
+
+func Test_Z_SpecUncovered(t *testing.T) {
+	testdata := `
+<rfc>
+  <middle>
+    <section anchor="intro" title="Introduction">
+	<t>Foo.</t>
+	<t><t>Sentence 1.</t></t>
+    </section>
+  </middle>
+</rfc>`
+	sp := readSpecCov(strings.NewReader(testdata))
+	sp.cover("1", "Foo. Sentence 1.")
+
+	want := specCoverage{
+		specPart{"1", "Foo."}:        true,
+		specPart{"1", "Sentence 1."}: true,
+	}
+
+	if !reflect.DeepEqual(sp, want) {
+		t.Errorf("got = %+v, want %+v", sp, want)
+	}
+
+	defer func() {
+		if err := recover(); err == nil {
+			t.Error("expected panic")
+		}
+	}()
+
+	sp.cover("1", "Not in spec.")
+}
+
+func TestSpecCoverage(t *testing.T) {
+	var notCovered bySpecSection
+	for p, covered := range defaultSpecCoverage {
+		if !covered {
+			notCovered = append(notCovered, p)
+		}
+	}
+	if len(notCovered) == 0 {
+		return
+	}
+	sort.Sort(notCovered)
+
+	const shortLen = 5
+	if testing.Short() && len(notCovered) > shortLen {
+		notCovered = notCovered[:shortLen]
+	}
+	t.Logf("COVER REPORT:")
+	for _, p := range notCovered {
+		t.Errorf("\tSECTION %s: %s", p.section, p.sentence)
+	}
+}