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

Bring back the Exclusive Flag #2781

Merged
merged 8 commits into from Jun 12, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
99 changes: 38 additions & 61 deletions draft-ietf-quic-http.md
Expand Up @@ -599,6 +599,11 @@ the orphan placeholder if progress can be made on descendants of the root. The
structure of the dependency tree changes as PRIORITY frames modify the
dependency links between other prioritized elements.

An exclusive flag allows for the insertion of a new level of dependencies. The
exclusive flag causes the prioritized element to become the sole dependency of
its parent, causing other dependencies to become dependent on the exclusive
element.

All dependent streams are allocated an integer weight between 1 and 256
(inclusive), derived by adding one to the weight expressed in the PRIORITY
frame.
Expand All @@ -620,9 +625,8 @@ When a prioritized element is first created, it has a default initial weight of
orphan placeholder; pushes are dependent on the client request on which the
PUSH_PROMISE frame was sent.

Requests may override the default initial values by including a PRIORITY frame
(see {{frame-priority}}) at the beginning of the stream. These priorities
can be updated by sending a PRIORITY frame on the control stream.
Priorities can be updated by sending a PRIORITY frame (see {{frame-priority}})
on the control stream.

### Placeholders

Expand Down Expand Up @@ -1024,7 +1028,7 @@ comparison between HTTP/2 and HTTP/3 frames is provided in {{h2-frames}}.
| -------------- | -------------- | -------------- | ----------- | ------------------------ |
| DATA | No | Yes | Yes | {{frame-data}} |
| HEADERS | No | Yes | Yes | {{frame-headers}} |
| PRIORITY | Yes | Yes (1) | No | {{frame-priority}} |
| PRIORITY | Yes | No | No | {{frame-priority}} |
| CANCEL_PUSH | Yes | No | No | {{frame-cancel-push}} |
| SETTINGS | Yes (1) | No | No | {{frame-settings}} |
| PUSH_PROMISE | No | Yes | No | {{frame-push-promise}} |
Expand Down Expand Up @@ -1127,22 +1131,14 @@ request using the corresponding stream ID, a server push using a Push ID (see
{{frame-push-promise}}), or a placeholder using a Placeholder ID (see
{{placeholders}}).

When a client initiates a request, a PRIORITY frame MAY be sent as the first
frame of the stream, creating a dependency on an existing element. In order to
ensure that prioritization is processed in a consistent order, any subsequent
PRIORITY frames for that request MUST be sent on the control stream. A
PRIORITY frame received after other frames on a request stream MUST be treated
as a connection error of type HTTP_UNEXPECTED_FRAME.

If, by the time a new request stream is opened, its priority information
has already been received via the control stream, the PRIORITY frame
sent on the request stream MUST be ignored.
In order to ensure that prioritization is processed in a consistent order,
PRIORITY frames MUST be sent on the control stream.

~~~~~~~~~~ drawing
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|PT |DT | Empty | [Prioritized Element ID (i)] ...
|PT |DT |X|Empty| Prioritized Element ID (i) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| [Element Dependency ID (i)] ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Expand All @@ -1155,22 +1151,25 @@ The PRIORITY frame payload has the following fields:

PT (Prioritized Element Type):
: A two-bit field indicating the type of element being prioritized (see
{{prioritized-element-types}}). When sent on a request stream, this MUST be
set to `11`. When sent on the control stream, this MUST NOT be set to `11`.
Copy link
Contributor

Choose a reason for hiding this comment

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

We probably want to retain the "MUST NOT be set to 11" here, even if we call it out as an error later.

Copy link
Member Author

Choose a reason for hiding this comment

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

Makes sense. Done in 0fd2717.

{{priority-element-types}}). This MUST NOT be set to `11`.

DT (Element Dependency Type):
: A two-bit field indicating the type of element being depended on (see
{{element-dependency-types}}).
{{priority-element-types}}).

X (Exclusive Flag):
: A single-bit flag indicating that the dependency is exclusive (see
{{priority}}).

Empty:
: A four-bit field which MUST be zero when sent and has no semantic value on
: A three-bit field which MUST be zero when sent and has no semantic value on
receipt.

Prioritized Element ID:
: A variable-length integer that identifies the element being prioritized.
Depending on the value of Prioritized Type, this contains the Stream ID of a
request stream, the Push ID of a promised resource, a Placeholder ID of a
placeholder, or is absent.
request stream, the Push ID of a promised resource, or a Placeholder ID of a
placeholder.

Element Dependency ID:
: A variable-length integer that identifies the element on which a dependency
Expand All @@ -1184,25 +1183,17 @@ The PRIORITY frame payload has the following fields:
element (see {{!HTTP2}}, Section 5.3). Add one to the value to obtain a
weight between 1 and 256.

The values for the Prioritized Element Type ({{prioritized-element-types}}) and
Element Dependency Type ({{element-dependency-types}}) imply the interpretation
of the associated Element ID fields.

| PT Bits | Type Description | Prioritized Element ID Contents |
| ------- | ---------------- | ------------------------------- |
| 00 | Request stream | Stream ID |
| 01 | Push stream | Push ID |
| 10 | Placeholder | Placeholder ID |
| 11 | Current stream | Absent |
Copy link
Contributor

Choose a reason for hiding this comment

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

Since the value of 11 was the only difference between these, we could re-combine them to a single table and simply say that prioritizing Root is invalid. (Which you already have on line 1213.)

Copy link
Member Author

Choose a reason for hiding this comment

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

That's a nice simplification! Done in 5cca97b.

{: #prioritized-element-types title="Prioritized Element Types"}

| DT Bits | Type Description | Element Dependency ID Contents |
| ------- | ---------------- | ------------------------------ |
| 00 | Request stream | Stream ID |
| 01 | Push stream | Push ID |
| 10 | Placeholder | Placeholder ID |
| 11 | Root of the tree | Absent |
{: #element-dependency-types title="Element Dependency Types"}
The values for the Prioritized Element Type and Element Dependency Type
({{priority-element-types}}) imply the interpretation of the associated Element
ID fields.

| Type Bits | Type Description | Element ID Contents |
| --------- | ---------------- | ------------------- |
| 00 | Request stream | Stream ID |
| 01 | Push stream | Push ID |
| 10 | Placeholder | Placeholder ID |
| 11 | Root of the tree | Absent |
{: #priority-element-types title="Element Types of a PRIORITY frame"}

Note that unlike in {{!HTTP2}}, the root of the tree cannot be referenced
using a Stream ID of 0, as in QUIC stream 0 carries a valid HTTP request. The
Expand All @@ -1213,12 +1204,7 @@ on the stream on which it is sent or its position in the stream. These
situations MUST be treated as a connection error of type HTTP_MALFORMED_FRAME.
The following situations are examples of invalid PRIORITY frames:

- A PRIORITY frame sent on a request stream with the Prioritized Element Type
set to any value other than `11`
- A PRIORITY frame sent on a request stream which expresses a dependency on a
request with a greater Stream ID than the current stream
- A PRIORITY frame sent on a control stream with the Prioritized Element Type
set to `11`
- A PRIORITY frame with the Prioritized Element Type set to `11`.
- A PRIORITY frame which claims to reference a request, but the associated ID
does not identify a client-initiated bidirectional stream

Expand All @@ -1229,8 +1215,8 @@ A PRIORITY frame that references a non-existent Push ID, a Placeholder ID
greater than the server's limit, or a Stream ID the client is not yet permitted
to open MUST be treated as a connection error of type HTTP_LIMIT_EXCEEDED.

A PRIORITY frame received on any stream other than a request or control stream
MUST be treated as a connection error of type HTTP_WRONG_STREAM.
A PRIORITY frame received on any stream other than the control stream MUST be
treated as a connection error of type HTTP_WRONG_STREAM.

PRIORITY frames received by a client MUST be treated as a connection error of
type HTTP_UNEXPECTED_FRAME.
Expand Down Expand Up @@ -1992,19 +1978,10 @@ commutative, both sender and receiver must apply them in the same order to
ensure that both sides have a consistent view of the stream dependency tree.

To achieve in-order delivery of priority changes in HTTP/3, PRIORITY frames are
sent as the first frame on a request stream or on the control stream. Because
ordering between these streams is not guaranteed, the assumption that the
PRIORITY frame on the request stream, if any, always comes first is explicitly
stated.

Exclusive prioritization has been removed, since implicitly reprioritizing other
streams which might or might not exist yet is prone to race conditions even with
the assumptions used to permit initial PRIORITY frames on request streams.

HTTP/3 permits the prioritization of requests, pushes and placeholders that each
exist in separate identifier spaces. The HTTP/3 PRIORITY frame replaces the
stream dependency field with fields that can identify the element of interest
and its dependency.
sent on the control stream. HTTP/3 permits the prioritization of requests,
pushes and placeholders that each exist in separate identifier spaces. The
HTTP/3 PRIORITY frame replaces the stream dependency field with fields that can
identify the element of interest and its dependency.

### Header Compression Differences

Expand Down