diff --git a/draft-ietf-quic-http.md b/draft-ietf-quic-http.md index 702592e35e..e60c80c35a 100644 --- a/draft-ietf-quic-http.md +++ b/draft-ietf-quic-http.md @@ -468,19 +468,27 @@ HEADERS frames can only be sent on request / push streams. ### PRIORITY {#frame-priority} -The PRIORITY (type=0x02) frame specifies the sender-advised priority of a -stream. In order to ensure that prioritization is processed in a consistent -order, PRIORITY frames MUST be sent on the control stream. A PRIORITY frame -sent on any other stream MUST be treated as a connection error of type -HTTP_WRONG_STREAM. +The PRIORITY (type=0x02) frame specifies the client-advised priority of a +stream. + +When opening a new request stream, 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 MUST be sent on the control stream. A PRIORITY frame received +after other frames on a request stream MUST be treated as a stream error of type +HTTP_UNEXPECTED_FRAME. + +Subsequent PRIORITY frames sent on the control stream might arrive before +PRIORITY frames sent on a request stream due to reordering. PRIORITY frames on +the control stream always take precedence. ~~~~~~~~~~ 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|E| Prioritized Element ID (i) ... +|PT |DT | Empty | [Prioritized Element ID (i)] ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Element Dependency ID (i) ... +| [Element Dependency ID (i)] ... +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Weight (8) | +-+-+-+-+-+-+-+-+ @@ -490,30 +498,28 @@ HTTP_WRONG_STREAM. The PRIORITY frame payload has the following fields: Prioritized Type: - : A two-bit field indicating the type of element being prioritized. + : A two-bit field indicating the type of element being prioritized. 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`. Dependency Type: : A two-bit field indicating the type of element being depended on. Empty: - : A three-bit field which MUST be zero when sent and MUST be ignored + : A four-bit field which MUST be zero when sent and MUST be ignored on receipt. - Exclusive: - : A flag which indicates that the stream dependency is exclusive (see - {{!RFC7540}}, Section 5.3). - 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, or a Placeholder ID of a - placeholder. + request stream, the Push ID of a promised resource, a Placeholder ID of a + placeholder, or is absent. Element Dependency ID: : A variable-length integer that identifies the element on which a dependency is being expressed. Depending on the value of Dependency Type, this contains the Stream ID of a request stream, the Push ID of a promised resource, the - Placeholder ID of a placeholder, or is ignored. For details of + Placeholder ID of a placeholder, or is absent. For details of dependencies, see {{priority}} and {{!RFC7540}}, Section 5.3. Weight: @@ -530,17 +536,28 @@ request using the corresponding stream ID, a server push using a Push ID (see The values for the Prioritized Element Type and Element Dependency Type 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 | Ignored | +| Type 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 | + +| Type 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 | Note that the root of the tree cannot be referenced using a Stream ID of 0, as in {{!RFC7540}}; QUIC stream 0 carries a valid HTTP request. The root of the -tree cannot be reprioritized. A PRIORITY frame that prioritizes the root of the -tree MUST be treated as a connection error of type HTTP_MALFORMED_FRAME. +tree cannot be reprioritized. A PRIORITY frame sent on a request stream with the +Prioritized Element Type set to any value other than `11` or which expresses a +dependency on a request with a greater Stream ID than the current stream MUST be +treated as a stream error of type HTTP_MALFORMED_FRAME. Likewise, a PRIORITY +frame sent on a control stream with the Prioritized Element Type set to `11` +MUST be treated as a connection error of type HTTP_MALFORMED_FRAME. When a PRIORITY frame claims to reference a request, the associated ID MUST identify a client-initiated bidirectional stream. A server MUST treat receipt @@ -551,6 +568,11 @@ A PRIORITY frame that references a non-existent Push ID or a Placeholder ID greater than the server's limit MUST be treated as an HTTP_MALFORMED_FRAME error. +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. + +PRIORITY frames received by a client MUST be treated as a stream error of type +HTTP_UNEXPECTED_FRAME. ### CANCEL_PUSH {#frame-cancel-push} @@ -1032,14 +1054,18 @@ another request, which expresses the preference that the latter stream (the "dependent" request). Taken together, the dependencies across all requests in a connection form a dependency tree. -When a client request is first sent or a placeholder first allocated, the -element is dependent on the root of the priority tree. Pushed streams are -initially dependent on the client request on which the PUSH_PROMISE frame was -sent. In all cases, elements are assigned an initial weight of 16. +When a client request is first sent, its parent and weight are determined by the +PRIORITY frame (see {{frame-priority}}) which begins the stream, if present. +Otherwise, the element is dependent on the root of the priority tree. +Placeholders are also dependent on the root of the priority tree when first +allocated. Pushed streams are initially dependent on the client request on +which the PUSH_PROMISE frame was sent. In all cases, elements are assigned an +initial weight of 16 unless an PRIORITY frame begins the stream. -The structure of the dependency tree changes as PRIORITY frames modify the -dependency links between requests. The PRIORITY frame {{frame-priority}} -identifies a prioritized element. The elements which can be prioritized are: +The structure of the dependency tree changes as PRIORITY frames on the control +stream modify the dependency links between requests. The PRIORITY frame +{{frame-priority}} identifies a prioritized element. The elements which can be +prioritized are: - Requests, identified by the ID of the request stream - Pushes, identified by the Push ID of the promised resource @@ -1709,8 +1735,8 @@ 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. HTTP/2 specifies priority assignments in PRIORITY frames and (optionally) in HEADERS frames. To achieve in-order delivery of priority changes in HTTP/3, -PRIORITY frames are sent on the control stream and the PRIORITY section is -removed from the HEADERS frame. +PRIORITY frames are sent on the control stream and exclusive prioritization +has been removed. Likewise, HPACK was designed with the assumption of in-order delivery. A sequence of encoded header blocks must arrive (and be decoded) at an endpoint in