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
Limit pushes using MAX_PUSH_ID #711
Changes from all commits
a7ac6f1
0926843
4bcc8b8
3b7aa26
f633213
9b96a44
b38ae53
494a48f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -336,9 +336,9 @@ frame. | |
## Server Push | ||
|
||
HTTP/QUIC supports server push as described in {{!RFC7540}}. During connection | ||
establishment, the client indicates whether it is willing to receive server | ||
pushes via the SETTINGS_ENABLE_PUSH setting in the SETTINGS frame (see | ||
{{connection-establishment}}), which is disabled by default. | ||
establishment, the client enables server push by sending a MAX_PUSH_ID frame | ||
(see {{frame-max-push-id}}). A server cannot use server push until it receives | ||
a MAX_PUSH_ID frame. | ||
|
||
As with server push for HTTP/2, the server initiates a server push by sending a | ||
PUSH_PROMISE frame that includes request header fields attributed to the | ||
|
@@ -362,9 +362,19 @@ This header consists of a 32-bit Push ID, which identifies a server push (see | |
~~~~~ | ||
{: #fig-push-stream-header title="Push Stream Header"} | ||
|
||
A push stream always starts with a 32-bit Push ID. A client MUST treat | ||
receiving a push stream that contains fewer than 4 octets as a connection error | ||
of type HTTP_MALFORMED_PUSH. | ||
|
||
A server SHOULD use Push IDs sequentially, starting at 0. A client uses the | ||
MAX_PUSH_ID frame ({{frame-max-push-id}}) to limit the number of pushes that a | ||
server can promise. 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 | ||
HTTP_MALFORMED_PUSH. | ||
|
||
Each Push ID MUST only be used once in a push stream header. If a push stream | ||
header includes a Push ID that was used in another push stream header, the | ||
client MUST treat this as a connection error of type HTTP_DUPLICATE_PUSH. The | ||
client MUST treat this as a connection error of type HTTP_MALFORMED_PUSH. The | ||
same Push ID can be used in multiple PUSH_PROMISE frames (see | ||
{{frame-push-promise}}). | ||
|
||
|
@@ -635,9 +645,6 @@ The following settings are defined in HTTP/QUIC: | |
SETTINGS_HEADER_TABLE_SIZE (0x1): | ||
: An integer with a maximum value of 2^32 - 1. This value MUST be zero. | ||
|
||
SETTINGS_ENABLE_PUSH (0x2): | ||
: Transmitted as a Boolean | ||
|
||
SETTINGS_MAX_HEADER_LIST_SIZE (0x6): | ||
: An integer with a maximum value of 2^32 - 1 | ||
|
||
|
@@ -696,6 +703,11 @@ Push ID: | |
Header Block: | ||
: HPACK-compressed request headers for the promised response. | ||
|
||
A server MUST NOT use a Push ID that is larger than the client has provided in a | ||
MAX_PUSH_ID frame ({{frame-max-push-id}}). A client MUST treat receipt of a | ||
PUSH_PROMISE that contains a larger Push ID than the client has advertised as a | ||
connection error of type HTTP_MALFORMED_PUSH_PROMISE. | ||
|
||
A server MAY use the same Push ID in multiple PUSH_PROMISE frames. This allows | ||
the server to use the same server push in response to multiple concurrent | ||
requests. Referencing the same server push ensures that a PUSH_PROMISE can be | ||
|
@@ -797,6 +809,38 @@ the server MAY send another GOAWAY frame with an updated last stream identifier. | |
This ensures that a connection can be cleanly shut down without losing requests. | ||
|
||
|
||
# MAX_PUSH_ID {#frame-max-push-id} | ||
|
||
The MAX_PUSH_ID frame (type=0xD) is used by clients to control the number of | ||
server pushes that the server can initiate. This sets the maximum value for a | ||
Push ID that the server can use in a PUSH_PROMISE frame. Consequently, this | ||
also limits the number of push streams that the server can initiate in addition | ||
to the limit set by the QUIC MAX_STREAM_ID frame. | ||
|
||
The MAX_PUSH_ID frame is always sent on the control stream. Receipt of a | ||
MAX_PUSH_ID frame on any other stream MUST be treated as a connection error of | ||
type HTTP_WRONG_STREAM. | ||
|
||
A server MUST NOT send a MAX_PUSH_ID frame. A client MUST treat the receipt of | ||
a MAX_PUSH_ID frame as a connection error of type HTTP_MALFORMED_MAX_PUSH_ID. | ||
|
||
The maximum Push ID is unset when a connection is created, meaning that a server | ||
cannot push until it receives a MAX_PUSH_ID frame. A client that wishes to | ||
manage the number of promised server pushes can increase the maximum Push ID by | ||
sending a MAX_PUSH_ID frame as the server fulfills or cancels server pushes. | ||
|
||
The MAX_PUSH_ID frame has no defined flags. | ||
|
||
The MAX_PUSH_ID frame carries a 32-bit Push ID that identifies the maximum value | ||
for a Push ID that the server can use (see {{frame-push-promise}}). A | ||
MAX_PUSH_ID frame cannot reduce the maximum Push ID; receipt of a MAX_PUSH_ID | ||
that contains a smaller value than previously received MUST be treated as a | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would explicitly state that this previous value may have been received via MAX_PUSH_ID or SETTINGS_MAX_PUSH_ID. Perhaps "a smaller value than that received via a previous MAX_PUSH_ID or SETTINGS_MAX_PUSH_ID ..." ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sending a frame with a value less than you provided in transport settings is a clear error, actually, since you know the transport settings necessarily came before the frame. |
||
connection error of type HTTP_MALFORMED_MAX_PUSH_ID. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. General comment: Because these are on the control stream, which means guaranteed in-order delivery, we could use the HTTP/2 model of sending an increment rather than an absolute number. I'm not sold that the few bytes saved are worth it, though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that we can make a bigger saving here by not sending the frame as often, noting that MAX_STREAM_ID covers the resource exhaustion issue. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think the savings are worth it, since this shouldn't be sent that often really as it is. On resource exhaustion, I think both MAX_STREAM_ID and MAX_PUSH_ID both cover that issue, just at different levels. QUIC decides MAX_STREAM_ID based on its resource constraints for streams, and the HTTP "layer" decides MAX_PUSH_ID based on its constraints for handling pushed resources. I think these are independent. |
||
|
||
A server MUST treat a MAX_PUSH_ID frame payload that is other than 4 octets in | ||
length as a connection error of type HTTP_MALFORMED_MAX_PUSH_ID. | ||
|
||
|
||
# Error Handling {#errors} | ||
|
||
QUIC allows the application to abruptly terminate (reset) individual streams or | ||
|
@@ -866,8 +910,11 @@ HTTP_WRONG_STREAM (0x0F): | |
HTTP_MULTIPLE_SETTINGS (0x10): | ||
: More than one SETTINGS frame was received. | ||
|
||
HTTP_DUPLICATE_PUSH (0x11): | ||
: Multiple push streams used the same Push ID. | ||
HTTP_MALFORMED_PUSH (0x11): | ||
: A push stream header was malformed or included an invalid Push ID. | ||
|
||
HTTP_MALFORMED_MAX_PUSH_ID (0x12): | ||
: A MAX_STREAM_ID frame has been received with an invalid format. | ||
|
||
|
||
# Considerations for Transitioning from HTTP/2 | ||
|
@@ -986,7 +1033,8 @@ SETTINGS_HEADER_TABLE_SIZE: | |
: See {{settings-parameters}}. | ||
|
||
SETTINGS_ENABLE_PUSH: | ||
: See {{settings-parameters}}. | ||
: This is removed in favor of the MAX_PUSH_ID which provides a more granular | ||
control over server push. | ||
|
||
SETTINGS_MAX_CONCURRENT_STREAMS: | ||
: QUIC controls the largest open stream ID as part of its flow control logic. | ||
|
@@ -1151,6 +1199,7 @@ The entries in the following table are registered by this document. | |
| GOAWAY | 0x7 | {{frame-goaway}} | | ||
| Reserved | 0x8 | N/A | | ||
| Reserved | 0x9 | N/A | | ||
| MAX_PUSH_ID | 0xD | {{frame-max-push-id}} | | ||
|----------------|------|--------------------------| | ||
|
||
## Settings Parameters {#iana-settings} | ||
|
@@ -1185,7 +1234,7 @@ The entries in the following table are registered by this document. | |
| Setting Name | Code | Specification | | ||
|----------------------------|:----:|-------------------------| | ||
| HEADER_TABLE_SIZE | 0x1 | {{settings-parameters}} | | ||
| ENABLE_PUSH | 0x2 | {{settings-parameters}} | | ||
| Reserved | 0x2 | N/A | | ||
| Reserved | 0x3 | N/A | | ||
| Reserved | 0x4 | N/A | | ||
| Reserved | 0x5 | N/A | | ||
|
@@ -1240,7 +1289,8 @@ The entries in the following table are registered by this document. | |
| HTTP_INTERRUPTED_HEADERS | 0x0E | Incomplete HEADERS block | {{http-error-codes}} | | ||
| HTTP_WRONG_STREAM | 0x0F | A frame was sent on the wrong stream | {{http-error-codes}} | | ||
| HTTP_MULTIPLE_SETTINGS | 0x10 | Multiple SETTINGS frames | {{http-error-codes}} | | ||
| HTTP_DUPLICATE_PUSH | 0x11 | Duplicate server push | {{http-error-codes}} | | ||
| HTTP_MALFORMED_PUSH | 0x11 | Invalid push stream header | {{http-error-codes}} | | ||
| HTTP_MALFORMED_MAX_PUSH_ID | 0x12 | Invalid MAX_PUSH_ID frame | {{http-error-codes}} | | ||
|-----------------------------------|--------|----------------------------------------|----------------------| | ||
|
||
|
||
|
@@ -1255,6 +1305,10 @@ The original authors of this specification were Robbie Shade and Mike Warres. | |
> **RFC Editor's Note:** Please remove this section prior to publication of a | ||
> final version of this document. | ||
|
||
## Since draft-ietf-quic-http-05 | ||
|
||
- Made push ID sequential, add MAX_PUSH_ID, remove SETTINGS_ENABLE_PUSH (#709) | ||
|
||
## Since draft-ietf-quic-http-04 | ||
|
||
- Cite RFC 5234 (#404) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems silly but possible to send this with 0. Can you add a sentence that says this MUST be > 0?