Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace SETTINGS with EXTENDED_SETTINGS #80

Merged
merged 8 commits into from
Dec 15, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
256 changes: 215 additions & 41 deletions draft-ietf-quic-http.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ additional framing. Note that a request or response without a body will cause
this stream to be half-closed in the corresponding direction without
transferring data.

Pairs of streams must be utilized sequentially, with no gaps. The data stream
MUST be reserved with the QUIC implementation when the message control stream
is opened or reserved, and MUST be closed after transferring the body, or else
closed immediately after sending the request headers if there is no body.

HTTP does not need to do any separate multiplexing when using QUIC - data sent
over a QUIC stream always maps to a particular HTTP transaction. Requests and
responses are considered complete when the corresponding QUIC streams are closed
Expand All @@ -177,18 +182,19 @@ HTTP response on the same streams as the request.
An HTTP message (request or response) consists of:

1. for a response only, zero or more header blocks (a sequence of HEADERS frames
with End Header Block set on the last) on the control stream containing the
message headers of informational (1xx) HTTP responses (see {{!RFC7230}}, Section
3.2 and {{!RFC7231}}, Section 6.2),
with End Header Block set on the last) on the control stream containing the
message headers of informational (1xx) HTTP responses (see {{!RFC7230}},
Section 3.2 and {{!RFC7231}}, Section 6.2),

2. one header block on the control stream containing the message headers (see
{{!RFC7230}}, Section 3.2),
{{!RFC7230}}, Section 3.2),

3. the payload body (see {{!RFC7230}}, Section 3.3), sent on the data stream
3. the payload body (see {{!RFC7230}}, Section 3.3), sent on the data stream,

4. optionally, one header block on the control stream containing the
trailer-part, if present (see {{!RFC7230}}, Section 4.1.2).
trailer-part, if present (see {{!RFC7230}}, Section 4.1.2).

The data stream MUST be half-closed immediately after the transfer of the body.
If the message does not contain a body, the corresponding data stream MUST still
be half-closed without transferring any data. The "chunked" transfer encoding
defined in Section 4.1 of {{!RFC7230}} MUST NOT be used.
Expand Down Expand Up @@ -437,16 +443,76 @@ Frame type 0x3 is reserved.

### SETTINGS {#frame-settings}

The SETTINGS frame (type=0x04) is unmodified from {{!RFC7540}} (so far). It MUST
only be sent on the connection control stream (Stream 3).
The SETTINGS frame (type=0x4) conveys configuration parameters that affect how
endpoints communicate, such as preferences and constraints on peer behavior, and
is substantially different from {{!RFC7540}}. Individually, a SETTINGS parameter
can also be referred to as a "setting".

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 -- a peer uses SETTINGS to advertise a set
of supported values. The recipient can then choose which entries from this list
are also acceptable and proceed with the value it has chosen. (This choice could
be announced in a field of an extension frame, or in its own value in SETTINGS.)

Different values for the same parameter can be advertised by each peer. For
example, a client might permit a very large HPACK state table while a server
chooses to use a small one to conserve memory.

A SETTINGS frame MAY be sent at any time by either endpoint over the lifetime
of the connection.

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.

The SETTINGS frame defines the following flag:

REQUEST_ACK (0x1):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this will be formatted strangely. You should confirm with the manual and maybe check the build output.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build output looks fine to me -- is there something specific you're concerned about?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You indented here, but I don't believe that this will result in any indenting for the REQUEST_ACK line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. It's indented in the HTML, but not indented in the TXT. That's consistent with the rest of the document, and with RFC 7540, which uses the same non-indentation for definition lists. I'm inclined to leave it; if it distresses you, feel free to suggest a change. ;-)

: When set, bit 0 indicates that this frame contains values which the sender
wants to know were understood and applied. For more information, see
{{settings-synchronization}}.

The payload of a SETTINGS frame consists of zero or more parameters, each
consisting of an unsigned 16-bit setting identifier and a length-prefixed binary
value.

~~~~~~~~~~~~~~~
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) |B| Length (15) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Contents (?) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~~~~~~~~~~~~~~~
{: #fig-ext-settings title="SETTINGS value format"}

A zero-length content indicates that the setting value is a Boolean given by the
B bit. If Length is not zero, the B bit MUST be zero, and MUST be ignored by
receivers. The initial value of each setting is "false" unless otherwise
specified by the definition of the setting.

An implementation MUST ignore the contents for any EXTENDED_SETTINGS identifier
it does not understand.

SETTINGS frames always apply to a connection, never a single stream, and MUST
only be sent on the connection control stream (Stream 3). If an endpoint
receives an SETTINGS frame whose stream identifier field is anything other than
0x0, the endpoint MUST respond with a connection error.

The SETTINGS frame affects connection state. A badly formed or incomplete
SETTINGS frame MUST be treated as a connection error (Section 5.4.1) of type
PROTOCOL_ERROR.

As in HTTP/2, additional SETTINGS frames may be sent mid-connection by either
endpoint.
#### Integer encoding

TODO:
: Decide whether to acknowledge receipt of SETTINGS through empty SETTINGS
frames with ACK bit set, as in HTTP/2, or rely on transport- level
acknowledgment.
Settings which are integers are transmitted in network byte order. Leading
zero octets are permitted, but implementations SHOULD use only as many bytes as
are needed to represent the value. An integer MUST NOT be represented in more
bytes than would be used to transfer the maximum permitted value.

#### Defined SETTINGS Parameters

Expand All @@ -455,13 +521,13 @@ superseded by QUIC transport parameters in HTTP-over-QUIC. Below is a listing of
how each HTTP/2 SETTINGS parameter is mapped:

SETTINGS_HEADER_TABLE_SIZE:
: Sent in SETTINGS frame.
: An integer with a maximum value of 2^32 - 1.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a definition of how to encode integers in the field. Do we permit leading zero octets?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now that these are variable length does it need a max size? We can merge extended settings and talk about that as a different issue too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I think that's already a ridiculous size for a header table (64KB should be enough for anyone!), but I defined it that way mostly to retain parity with HTTP/2. For existing settings which are defined as integers already, might as well keep the same valid range where reasonable.


SETTINGS_ENABLE_PUSH:
: Sent in SETTINGS frame (TBD, currently set using QUIC "SPSH" connection
option)
: Transmitted as a Boolean. The default remains "true" as specified in
{{!RFC7540}}.

SETTINGS_MAX_CONCURRENT_STREAMS
SETTINGS_MAX_CONCURRENT_STREAMS:
: QUIC requires the maximum number of incoming streams per connection to be
specified in the initial crypto handshake, using the "MSPC" tag. Specifying
SETTINGS_MAX_CONCURRENT_STREAMS in the SETTINGS frame is an error.
Expand All @@ -476,14 +542,56 @@ how each HTTP/2 SETTINGS parameter is mapped:
: This setting has no equivalent in QUIC. Specifying it in the SETTINGS
frame is an error.

SETTINGS_MAX_HEADER_LIST_SIZE
: Sent in SETTINGS frame.
SETTINGS_MAX_HEADER_LIST_SIZE:
: An integer with a maximium value of 2^32 - 1.

As with HTTP/2, unknown SETTINGS parameters are tolerated but ignored. SETTINGS
parameters are acknowledged by the receiving peer, by sending an empty SETTINGS
frame in response with the ACK bit set.
#### Settings Synchronization {#settings-synchronization}

Some 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 MUST apply
the updated parameters as soon as possible upon receipt. 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, if the REQUEST_ACK flag was set, the
recipient MUST emit the following frames:

- On the connection control stream, a SETTINGS_ACK frame
({{frame-settings-ack}}) listing the identifiers whose values were not
understood.

- On each request control stream which is not in the "half-closed (local)" or
"closed" state, an empty SETTINGS_ACK frame.

The SETTINGS_ACK frame on the connection control stream contains the highest
stream number which was open at the time the SETTINGS frame was received. All
streams with higher numbers can safely be assumed to have the new settings in
effect when they open.

For already-open streams including the connection control stream, the
SETTINGS_ACK frame indicates the point at which the new settings took effect, if
they did so before the peer half-closed the stream. If the peer closed the
stream before receiving the SETTINGS frame, the previous settings were in effect
for the full lifetime of that stream.

In certain conditions, the SETTINGS_ACK frame can be the first frame on a given
stream -- this simply indicates that the new settings apply from the beginning
of that stream.

If the sender of a SETTINGS frame with the REQUEST_ACK flag set does not
receive full acknowledgement within a reasonable amount of time, it MAY issue a
connection error ([RFC7540] Section 5.4.1) of type SETTINGS_TIMEOUT. A full
acknowledgement has occurred when:

- All previous SETTINGS frames have been fully acknowledged,

- A SETTINGS_ACK frame has been received on the connection control stream,

- All message control streams with a Stream ID through those given in the
SETTINGS_ACK frame have either closed or received a SETTINGS_ACK frame.


### PUSH_PROMISE {#frame-push-promise}

The PUSH_PROMISE frame (type=0x05) is used to carry a request header set from
Expand Down Expand Up @@ -543,6 +651,43 @@ CONTINUATION frames do not exist, since larger supported HEADERS/PUSH_PROMISE
frames provide equivalent functionality. Frame type 0x9 is reserved.


### SETTINGS_ACK Frame {#frame-settings-ack}

The SETTINGS_ACK frame (id = 0x0b) acknowledges receipt and application
of specific values in the peer's SETTINGS frame. Depending on the stream where
it is sent, it takes two different forms.

On the connection control stream, it contains information about how and when the
sender has processed the most recently-received SETTINGS frame, and has the
following payload:

~~~~~~~~~~~~~~~
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Highest Local Stream (32) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Highest Remote Stream (32) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Unrecognized Identifiers (*) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~~~~~~~~~~~~~~~
{: #fig-settings-ack title="SETTINGS_ACK connection control stream format"}

Highest Local Stream (32 bits):
: The highest locally-initiated Stream ID which is not in the "idle" state

Highest Remote Stream (32 bits):
: The highest peer-initiated Stream ID which is not in the "idle" state

Unrecognized Identifiers:
: A list of 16-bit SETTINGS identifiers which the sender has not understood
and therefore ignored. This list MAY be empty.

On message control streams, the SETTINGS_ACK frame carries no payload, and is
strictly a synchronization marker for settings application. See
{{settings-synchronization}} for more detail.

# Error Handling {#errors}

The HTTP/2 error codes defined in Section 7 of {{!RFC7540}} map to QUIC error
Expand Down Expand Up @@ -602,35 +747,64 @@ HTTP/2.

# IANA Considerations

## Frame Types
## Existing Frame Types

This document adds two new columns to the "HTTP/2 Frame Type" registry defined in
{{!RFC7540}}:

Supported in HTTP/QUIC:
: Indicates whether the frame is also supported in this HTTP/QUIC mapping
Supported Protocols:
: Indicates which associated protocols use the frame type. Values MUST be one
of:

- "HTTP/2 only"
- "HTTP/QUIC only"
- "Both"

HTTP/QUIC Specification:
: Indicates where this frame's behavior over QUIC is defined; required
if the frame is supported over QUIC.

Values for existing registrations are assigned by this document:

+---------------|------------------------|-------------------------+
| Frame Type | Supported in HTTP/QUIC | HTTP/QUIC Specification |
|---------------|:----------------------:|-------------------------|
| DATA | No | N/A |
| HEADERS | Yes | {{frame-headers}} |
| PRIORITY | Yes | {{frame-priority}} |
| RST_STREAM | No | N/A |
| SETTINGS | Yes | {{frame-settings}} |
| PUSH_PROMISE | Yes | {{frame-push-promise}} |
| PING | No | N/A |
| GOAWAY | No | N/A |
| WINDOW_UPDATE | No | N/A |
| CONTINUATION | No | N/A |
+---------------|------------------------|-------------------------+

+---------------|---------------------|-------------------------+
| Frame Type | Supported Protocols | HTTP/QUIC Specification |
|---------------|:-------------------:|-------------------------|
| DATA | HTTP/2 only | N/A |
| HEADERS | Both | {{frame-headers}} |
| PRIORITY | Both | {{frame-priority}} |
| RST_STREAM | HTTP/2 only | N/A |
| SETTINGS | Both | {{frame-settings}} |
| PUSH_PROMISE | Both | {{frame-push-promise}} |
| PING | HTTP/2 only | N/A |
| GOAWAY | HTTP/2 only | N/A |
| WINDOW_UPDATE | HTTP/2 only | N/A |
| CONTINUATION | HTTP/2 only | N/A |
+---------------|---------------------|-------------------------+

The "Specification" column is renamed to "HTTP/2 specification" and is only
required if the frame is supported over HTTP/2.


## New Frame Types

This document adds one new entry to the "HTTP/2 Frame Type" registry defined in
{{!RFC7540}}:

Frame Type:
: SETTINGS_ACK

Code:
: 0x0b

HTTP/2 Specification:
: N/A

Supported Protocols:
: HTTP/QUIC only

HTTP/QUIC Specification:
: {{frame-settings-ack}}

--- back

# Contributors
Expand Down