Draft: draft-ietf-quic-http

Commentary: by copying the language we already had for frame types and taking suggestion from . 
 points out that SETTINGS and frames are different , because of tunneling intermediaries . The intermediary need not check every received frame for validity if they 're not processing the frames . SETTINGS , on the other hand , have to be checked because they 're inherently hop - by - hop . While I 'm not crazy about having SETTINGS and frames be different , there is at least a justification for it . 
 I 'm sorry that makes no sense . You ca n't pick and choose which parts of a protocol you understand . 
 : Does n't that argument then argue for MUST close the connection on error ? What am I missing ? 
 that goes back to the discussion we had around stream vs. connection errors . point , if I can summarize briefly , is that an intermediary might directly copy some things from its connection to the client onto its connection to the server , or vice versa . That led to the logic of using connection errors for things definitely generated by your peer ; settings are definitely generated by the peer , which argues for " MUST error , " while frames might have come from upstream . However , I note that we currently do n't specify whether receiving a reserved frame type is a stream or a connection error , so I 've opened for that . 
 I 'm going to argue that frames also need to definitely come from a peer . If SETTINGS definitely comes from an immediate peer , then transport - level intermediation is not valid . That is , you forward ( HTTP ) frames blindly at your own risk . That is , if you indicate in SETTINGS that you understand an extension and then blindly forward frames related to that extension , you are responsible for the effects . 
 When you argue that , do so on and we 'll invite for the cage match . For this issue / PR , it sounds like we have violent agreement that SETTINGS are a MUST - connection - error . 
 We currently say : This text has two failings : It does n't specify whether the error is a stream error or a connection error In , it was argued that this violation is easily detected , and perhaps warrants a " MUST error " instead of a " MAY error " 
 +1 to both changes from my perspective . 
 This sounds like a design issue . Since this spins off from and I 'm going to assume from past discussion that there is sufficient interest in discussing this . 
 MUST respond with a connection error SGTM . Frames are hop - by - hop ( compared to HTTP messages being end - to - end ) , therefore we can enforce this . 
 Thanks , This had shades of the tunneling discussion before , and I was n't sure on which side of that fence you 'd land . 
 Thank you for checking . As stated above , I think we can be strict regarding HTTP frames ( especially the types ) , even though I tend to think that we need to be lax about HTTP messages ( and how they are terminated ) . 
 We explicitly discuss what the behavior should be for H2 frame types that do n't have corresponding H3 frames . The same sort of reservation with IANA is done with settings , but is n't explicitly stated in the definition of SETTINGS . 
 Arguably editorial , since the text in the  clearly implies this was already intended to be the case , but fixing entails new  and MAY statements . 
 Lets run this as design for visibility . 
 or without  's changes . Nice !
Paragraph (version A):
Server push is an interaction mode introduced in HTTP/2 HTTP2 which
permits a server to push a request-response exchange to a client in
anticipation of the client making the indicated request.  This trades
off network usage against a potential latency gain.  Several HTTP/3
frames are used to manage server push, such as PUSH_PROMISE,
MAX_PUSH_ID, and CANCEL_PUSH.
Paragraph (version A):
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 based on draft-ietf-quic-
http-09 which reserves an extra stream for unsolicited transmission
of 1980s pop music might identify itself as "h3-09-rickroll".  Note
that any label MUST conform to the "token" syntax defined in
Section 5.4.1.1 of SEMANTICS.  Experimenters are encouraged to
coordinate their experiments on the quic@ietf.org [2] mailing list.
Paragraph (version B):
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 based on draft-ietf-quic-
http-09 that reserves an extra stream for unsolicited transmission of
1980s pop music might identify itself as "h3-09-rickroll".  Note that
any label MUST conform to the "token" syntax defined in
Section 5.4.1.1 of SEMANTICS.  Experimenters are encouraged to
coordinate their experiments on the quic@ietf.org mailing list.
Paragraph (version A):
On receipt of an Alt-Svc record indicating HTTP/3 support, a client
MAY attempt to establish a QUIC connection to the indicated host and
port and, if successful, send HTTP requests using the mapping
described in this document.
Paragraph (version B):
On receipt of an Alt-Svc record indicating HTTP/3 support, a client
MAY attempt to establish a QUIC connection to the indicated host and
port; if this connection is successful, the client can send HTTP
requests using the mapping described in this document.
Paragraph (version B):
Although HTTP is independent of the transport protocol, the "http"
scheme associates authority with the ability to receive TCP
connections on the indicated port of whatever host is identified
within the authority component.  Because HTTP/3 does not use TCP,
HTTP/3 cannot be used for direct access to the authoritative server
for a resource identified by an "http" URI.  However, protocol
extensions such as ALTSVC permit the authoritative server to identify
other services that are also authoritative and that might be
reachable over HTTP/3.
Paragraph (version A):
Clients SHOULD NOT open more than one HTTP/3 connection to a given
host and port pair, where the host is derived from a URI, a selected
alternative service ALTSVC, or a configured proxy.  A client MAY open
multiple connections to the same IP address and UDP port using
different transport or TLS configurations but SHOULD avoid creating
multiple connections with the same configuration.
Paragraph (version B):
A client sends an HTTP request on a client-initiated bidirectional
QUIC stream.  A client MUST send only a single request on a given
stream.  A server sends zero or more interim HTTP responses on the
same stream as the request, followed by a single final HTTP response,
as detailed below.  See Section 10 of SEMANTICS for a description of
interim and final HTTP responses.
Paragraph (version A):
the header field section (see Section 5 of SEMANTICS), sent as a
single HEADERS frame (see frame-headers),
Paragraph (version A):
optionally, the payload body, if present (see Section 7.3.3 of
SEMANTICS), sent as a series of DATA frames (see frame-data),
Paragraph (version A):
optionally, the trailer field section, if present (see Section 5.6
of SEMANTICS), sent as a single HEADERS frame.
Paragraph (version A):
A server MAY send one or more PUSH_PROMISE frames (see frame-push-
promise) before, after, or interleaved with the frames of a response
message.  These PUSH_PROMISE frames are not part of the response; see
server-push for more details.  These frames are not permitted in
pushed responses; a pushed response which includes PUSH_PROMISE
frames MUST be treated as a connection error of type
H3_FRAME_UNEXPECTED.
Paragraph (version B):
Header and trailer field sections are described in Section 5 of
SEMANTICS; the payload body is described in Section 7.3.3 of
SEMANTICS.
Paragraph (version A):
A response MAY consist of multiple messages when and only when one or
more informational responses (1xx; see Section 10.2 of SEMANTICS)
precede a final response to the same request.  Interim responses do
not contain a payload body or trailers.
Paragraph (version B):
A response MAY consist of multiple messages when and only when one or
more interim responses (1xx; see Section 10.2 of SEMANTICS) precede a
final response to the same request.  Interim responses do not contain
a payload body or trailers.
Paragraph (version B):
To allow for better compression efficiency, the "Cookie" field
(RFC6265) MAY be split into separate field lines, each with one or
more cookie-pairs, before compression.  If a decompressed field
section contains multiple cookie field lines, 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
context other than HTTP/2 or HTTP/3, such as an HTTP/1.1 connection,
or a generic HTTP server application.
Paragraph (version A):
If a stream is cancelled after receiving a complete response, the
client MAY ignore the cancellation and use the response.  However, if
a stream is cancelled after receiving a partial response, the
response SHOULD NOT be used.  Automatically retrying such requests is
not possible, unless this is otherwise permitted (e.g., idempotent
actions like GET, PUT, or DELETE).
Paragraph (version B):
If an implementation wishes to advise its peer of this limit, it can
be conveyed as a number of bytes in the
SETTINGS_MAX_FIELD_SECTION_SIZE parameter.  An implementation that
has received this parameter SHOULD NOT send an HTTP message header
that exceeds the indicated size, as the peer will likely refuse to
process it.  However, because this limit is applied at each hop,
messages below this limit are not guaranteed to be accepted.
Paragraph (version B):
If a stream is canceled after receiving a complete response, the
client MAY ignore the cancellation and use the response.  However, if
a stream is cancelled after receiving a partial response, the
response SHOULD NOT be used.  Automatically retrying such requests is
not possible, unless this is otherwise permitted (e.g., idempotent
actions like GET, PUT, or DELETE).
Paragraph (version A):
All DATA frames on the stream correspond to data sent or received on
the TCP connection.  Any DATA frame sent by the client is transmitted
by the proxy to the TCP server; data received from the TCP server is
packaged into DATA frames by the proxy.  Note that the size and
number of TCP segments is not guaranteed to map predictably to the
size and number of HTTP DATA or QUIC STREAM frames.
Paragraph (version A):
The TCP connection can be closed by either peer.  When the client
ends the request stream (that is, the receive stream at the proxy
enters the "Data Recvd" state), the proxy will set the FIN bit on its
connection to the TCP server.  When the proxy receives a packet with
the FIN bit set, it will terminate the send stream that it sends to
the client.  TCP connections which remain half-closed in a single
direction are not invalid, but are often handled poorly by servers,
so clients SHOULD NOT close a stream for sending while they still
expect to receive data from the target of the CONNECT.
Paragraph (version A):
Server push is an interaction mode which permits a server to push a
request-response exchange to a client in anticipation of the client
making the indicated request.  This trades off network usage against
a potential latency gain.  HTTP/3 server push is similar to what is
described in HTTP/2 HTTP2, but uses different mechanisms.
Paragraph (version A):
Server push is only enabled on a connection when a client sends a
MAX_PUSH_ID frame; see frame-max-push-id.  A server cannot use server
push until it receives a MAX_PUSH_ID frame.  A client sends
additional MAX_PUSH_ID frames to control the number of pushes that a
server can promise.  A server SHOULD use Push IDs sequentially,
starting at 0.  A client MUST treat receipt of a push stream with a
Push ID that is greater than the maximum Push ID as a connection
error of type H3_ID_ERROR.
Paragraph (version B):
Each server push is assigned a unique Push ID by the server.  The
Push ID is used to refer to the push in various contexts throughout
the lifetime of the connection.
Paragraph (version B):
The Push ID space begins at zero, and ends at a maximum value set by
the MAX_PUSH_ID frame; see frame-max-push-id.  In particular, a
server is not able to push until after the client sends a MAX_PUSH_ID
frame.  A client sends MAX_PUSH_ID frames to control the number of
pushes that a server can promise.  A server SHOULD use Push IDs
sequentially, beginning from zero.  A client MUST treat receipt of a
push stream with a Push ID that is greater than the maximum Push ID
as a connection error of type H3_ID_ERROR.
Paragraph (version B):
The Push ID is used in one or more PUSH_PROMISE frames (frame-push-
promise) that carry the header section of the request message.  These
frames are sent on the request stream that generated the push.  This
allows the server push to be associated with a client request.  When
the same Push ID is promised on multiple request streams, the
decompressed request field sections MUST contain the same fields in
the same order, and both the name and the value in each field MUST be
identical.
Paragraph (version B):
The Push ID is then included with the push stream that ultimately
fulfills those promises; see push-streams.  The push stream
identifies the Push ID of the promise that it fulfills, then contains
a response to the promised request as described in request-response.
Paragraph (version B):
Finally, the Push ID can be used in CANCEL_PUSH frames; see frame-
cancel-push.  Clients use this frame to indicate they do not wish to
receive a promised resource.  Servers use this frame to indicate they
will not be fulfilling a previous promise.
Paragraph (version A):
Clients SHOULD send a CANCEL_PUSH frame upon receipt of a
PUSH_PROMISE frame carrying a request which is not cacheable, is not
known to be safe, that indicates the presence of a request body, or
for which it does not consider the server authoritative.
Paragraph (version A):
Ordering of a PUSH_PROMISE in relation to certain parts of the
response is important.  The server SHOULD send PUSH_PROMISE frames
prior to sending HEADERS or DATA frames that reference the promised
responses.  This reduces the chance that a client requests a resource
that will be pushed by the server.
Paragraph (version A):
When a server later fulfills a promise, the server push response is
conveyed on a push stream; see push-streams.  The push stream
identifies the Push ID of the promise that it fulfills, then contains
a response to the promised request using the same format described
for responses in request-response.
Paragraph (version B):
Push stream data can also arrive after a client has canceled a push.
In this case, the client can abort reading the stream with an error
code of H3_REQUEST_CANCELLED.  This asks the server not to transfer
additional data and indicates that it will be discarded upon receipt.
Paragraph (version B):
Even when a connection is not idle, either endpoint can decide to
stop using the connection and initiate a graceful connection close.
Endpoints initiate the graceful shutdown of a connection by sending a
GOAWAY frame (frame-goaway).  The GOAWAY frame contains an identifier
that indicates to the receiver the range of requests or pushes that
were or might be processed in this connection.  The server sends a
client-initiated bidirectional Stream ID; the client sends a Push ID
(server-push).  Requests or pushes with the indicated identifier or
greater are rejected (request-cancellation) by the sender of the
GOAWAY.  This identifier MAY be zero if no requests or pushes were
processed.
Paragraph (version B):
An HTTP/3 implementation can immediately close the QUIC connection at
any time.  This results in sending a QUIC CONNECTION_CLOSE frame to
the peer indicating that the application layer has terminated the
connection.  The application error code in this frame indicates to
the peer why the connection is being closed.  See errors for error
codes that can be used when closing a connection in HTTP/3.
Paragraph (version A):
For various reasons, the QUIC transport could indicate to the
application layer that the connection has terminated.  This might be
due to an explicit closure by the peer, a transport-level error, or a
change in network topology which interrupts connectivity.
Paragraph (version A):
If a connection terminates without a GOAWAY frame, clients MUST
assume that any request which was sent, whether in whole or in part,
might have been processed.
Paragraph (version B):
For various reasons, the QUIC transport could indicate to the
application layer that the connection has terminated.  This might be
due to an explicit closure by the peer, a transport-level error, or a
change in network topology that interrupts connectivity.
Paragraph (version A):
Implementations MAY send stream types before knowing whether the peer
supports them.  However, stream types which could modify the state or
semantics of existing protocol components, including QPACK or other
extensions, MUST NOT be sent until the peer is known to support them.
Paragraph (version B):
Implementations MAY send stream types before knowing whether the peer
supports them.  However, stream types that could modify the state or
semantics of existing protocol components, including QPACK or other
extensions, MUST NOT be sent until the peer is known to support them.
Paragraph (version B):
Each side MUST initiate a single control stream at the beginning of
the connection and send its SETTINGS frame as the first frame on this
stream.  If the first frame of the control stream is any other frame
type, this MUST be treated as a connection error of type
H3_MISSING_SETTINGS.  Only one control stream per peer is permitted;
receipt of a second stream claiming to be a control stream MUST be
treated as a connection error of type H3_STREAM_CREATION_ERROR.  The
sender MUST NOT close the control stream, and the receiver MUST NOT
request that the sender close the control stream.  If either control
stream is closed at any point, this MUST be treated as a connection
error of type H3_CLOSED_CRITICAL_STREAM.
Paragraph (version A):
HTTP frames are carried on QUIC streams, as described in stream-
mapping.  HTTP/3 defines three stream types: control stream, request
stream, and push stream.  This section describes HTTP/3 frame formats
and the streams types on which they are permitted; see stream-frame-
mapping for an overview.  A comparison between HTTP/2 and HTTP/3
frames is provided in h2-frames.
Paragraph (version A):
DATA frames (type=0x0) convey arbitrary, variable-length sequences of
bytes associated with an HTTP request or response payload.
Paragraph (version B):
The CANCEL_PUSH frame (type=0x3) is used to request cancellation of a
server push prior to the push stream being received.  The CANCEL_PUSH
frame identifies a server push by Push ID (see server-push), encoded
as a variable-length integer.
Paragraph (version A):
SETTINGS parameters are not negotiated; they describe characteristics
of the sending peer, which can be used by the receiving peer.
However, a negotiation can be implied by the use of SETTINGS - each
peer uses SETTINGS to advertise a set of supported values.  The
definition of the setting would describe how each peer combines the
two sets to conclude which choice will be used.  SETTINGS does not
provide a mechanism to identify when the choice takes effect.
Paragraph (version A):
An HTTP implementation MUST NOT send frames or requests which would
be invalid based on its current understanding of the peer's settings.
Paragraph (version B):
An HTTP implementation MUST NOT send frames or requests that would be
invalid based on its current understanding of the peer's settings.
Paragraph (version A):
For clients using a 1-RTT QUIC connection, the initial value of each
server setting is the default value.  1-RTT keys will always become
available prior to SETTINGS arriving, even if the server sends
SETTINGS immediately.  Clients SHOULD NOT wait indefinitely for
SETTINGS to arrive before sending requests, but SHOULD process
received datagrams in order to increase the likelihood of processing
SETTINGS before sending the first request.
Paragraph (version A):
Allowing duplicate references to the same Push ID is primarily to
reduce duplication caused by concurrent requests.  A server SHOULD
avoid reusing a Push ID over a long period.  Clients are likely to
consume server push responses and not retain them for reuse over
time.  Clients that see a PUSH_PROMISE that uses a Push ID that they
have already consumed and discarded are forced to ignore the
PUSH_PROMISE.
Paragraph (version B):
A server MAY use the same Push ID in multiple PUSH_PROMISE frames.
If so, the decompressed request header sets MUST contain the same
fields in the same order, and both the name and the value in each
field MUST be exact matches.  Clients SHOULD compare the request
header sections for resources promised multiple times.  If a client
receives a Push ID that has already been promised and detects a
mismatch, it MUST respond with a connection error of type
H3_GENERAL_PROTOCOL_ERROR.  If the decompressed field sections match
exactly, the client SHOULD associate the pushed content with each
stream on which a PUSH_PROMISE frame was received.
Paragraph (version B):
Allowing duplicate references to the same Push ID is primarily to
reduce duplication caused by concurrent requests.  A server SHOULD
avoid reusing a Push ID over a long period.  Clients are likely to
consume server push responses and not retain them for reuse over
time.  Clients that see a PUSH_PROMISE frame that uses a Push ID that
they have already consumed and discarded are forced to ignore the
promise.
Paragraph (version B):
The MAX_PUSH_ID frame carries a single variable-length integer that
identifies the maximum value for a Push ID that the server can use;
see server-push.  A MAX_PUSH_ID frame cannot reduce the maximum Push
ID; receipt of a MAX_PUSH_ID frame that contains a smaller value than
previously received MUST be treated as a connection error of type
H3_ID_ERROR.
Paragraph (version A):
This section describes HTTP/3-specific error codes which can be used
to express the cause of a connection or stream error.
Paragraph (version A):
Peer violated protocol requirements in a way which doesn't match a
more specific error code, or endpoint declines to use the more
specific error code.
Paragraph (version A):
This document doesn't mandate a specific method for negotiating the
use of an extension but notes that a setting (settings-parameters)
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 default
value MUST be defined in such a fashion that the extension is
disabled if the setting is omitted.
Paragraph (version A):
Similarly, HTTP/3 allows field values that are not valid.  While most
of the values that can be encoded will not alter field parsing,
carriage return (CR, ASCII 0xd), line feed (LF, ASCII 0xa), and the
zero character (NUL, ASCII 0x0) might be exploited by an attacker if
they are translated verbatim.  Any request or response that contains
a character not permitted in a field value MUST be treated as
malformed (malformed).  Valid characters are defined by the "field-
content" ABNF rule in Section 5.4 of SEMANTICS.
Paragraph (version B):
Similarly, HTTP/3 can transport field values that are not valid.
While most values that can be encoded will not alter field parsing,
carriage return (CR, ASCII 0xd), line feed (LF, ASCII 0xa), and the
zero character (NUL, ASCII 0x0) might be exploited by an attacker if
they are translated verbatim.  Any request or response that contains
a character not permitted in a field value MUST be treated as
malformed (malformed).  Valid characters are defined by the "field-
content" ABNF rule in Section 5.4 of SEMANTICS.
Paragraph (version B):
A server that receives a larger field section than it is willing to
handle can send an HTTP 431 (Request Header Fields Too Large) status
code (RFC6585).  A client can discard responses that it cannot
process.
Paragraph (version B):
Implementations communicating on a secure channel MUST NOT compress
content that includes both confidential and attacker-controlled data
unless separate compression contexts are used for each source of
data.  Compression MUST NOT be used if the source of data cannot be
reliably determined.
Paragraph (version B):
This document establishes a registry for HTTP/3 frame type codes.
The "HTTP/3 Frame Type" registry governs a 62-bit space.  This
registry follows the QUIC registry policy; see iana-policy.
Permanent registrations in this registry are assigned using the
Specification Required policy (RFC8126), except for values between
0x00 and 0x3f (in hexadecimal; inclusive), which are assigned using
Standards Action or IESG Approval as defined in Section 4.9 and 4.10
of RFC8126.
Paragraph (version B):
This document establishes a registry for HTTP/3 settings.  The
"HTTP/3 Settings" registry governs a 62-bit space.  This registry
follows the QUIC registry policy; see iana-policy.  Permanent
registrations in this registry are assigned using the Specification
Required policy (RFC8126), except for values between 0x00 and 0x3f
(in hexadecimal; inclusive), which are assigned using Standards
Action or IESG Approval as defined in Section 4.9 and 4.10 of
RFC8126.
Paragraph (version A):
A name for the error code.  Specifying an error code name is
optional.
Paragraph (version B):
This document establishes a registry for HTTP/3 error codes.  The
"HTTP/3 Error Code" registry manages a 62-bit space.  This registry
follows the QUIC registry policy; see iana-policy.  Permanent
registrations in this registry are assigned using the Specification
Required policy (RFC8126), except for values between 0x00 and 0x3f
(in hexadecimal; inclusive), which are assigned using Standards
Action or IESG Approval as defined in Section 4.9 and 4.10 of
RFC8126.
Paragraph (version B):
This document establishes a registry for HTTP/3 unidirectional stream
types.  The "HTTP/3 Stream Type" registry governs a 62-bit space.
This registry follows the QUIC registry policy; see iana-policy.
Permanent registrations in this registry are assigned using the
Specification Required policy (RFC8126), except for values between
0x00 and 0x3f (in hexadecimal; inclusive), which are assigned using
Standards Action or IESG Approval as defined in Section 4.9 and 4.10
of RFC8126.
Paragraph (version B):
Specifications for permanent registrations MUST include a description
of the stream type, including the layout and semantics of the stream
contents.