Draft: draft-ietf-quic-http

Commentary: Implements suggestions from 
 Updated to replace  and HTTPPUSHIDERROR with the single error HTTPID_ERROR . 
 There are presently a few cases where the Push ID can be used incorrectly . The table shows current error codes , proposes replacing the HTTPDUPLICATEPUSH with an HTTPPUSHIDERROR code , and replaces use of HTTPMALFORMED frame . Note , on I suggested a slightly different solution to replace   , but I think this is a better path . 
 To me it seems that having an error code for specific part of push ( i.e. ID of push - related information being incorrect ) a bit too detailed . I think it sticks out , because we do not have things like PLACEHOLDERIDERROR , STREAMIDERROR . Also , using PUSHIDERROR in some cases while using MALFORMEDFRAME in others seems confusing . I think we might want to consider doing either of the two : Use PUSHIDERROR ( or a generic error code for push ) for all the push - related errors . This makes sense if we consider push as an optional feature of HTTP/3 Introduce IDERROR that captures all the limit and ID errors . 
 Thanks The proposal is a bit of a compromise , so I agree with some of the points that you make . I like your idea of replacing  with HTTPIDERROR . I think it solves the issue in the most general way and does n't change the protocol mechanics . What follows is the response I made first , before coming to that agreement :) Right . The difference here is that H3 frames only reference the stream and placeholder ID spaces , they do n't control them . So , if the peer references an ID that does n't exist then respond with  . Multiple references to the same ID is a little different , its ok to reuse placeholder ID ( as long as the above condition holds , and you create a semantically valid PRIORITY frame ) . The transport spec discusses reuse of stream IDs at that layer ; in H3 we only use stream ID for PRIORITY and GOAWAY - this has similar restrictions . However , server push is a little different because it 's ID space is managed by the  frame . The three errors that use HTTPPUSHIDERROR are unique to push . However , if we modified  to cover exceeding limits and incorrect ID usage ( call it HTTPID_ERROR ) I think that would work . 
 I updated the PR with the above , so that we can see what it looks like . 
 I 'm not totally sold on this , but I 'm having trouble articulating what it is that does n't flow for me . I suspect that means I do n't actually disagree , I just need some time to wrap my head around it . 
 We merged so I 'm closing this as completed .
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 HTTP_LIMIT_EXCEEDED.
Paragraph (version B):
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 HTTP_ID_ERROR.
Paragraph (version A):
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.
Paragraph (version B):
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_ID_ERROR.
Paragraph (version A):
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.
Paragraph (version B):
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_ID_ERROR.
Paragraph (version A):
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) and MUST NOT use
the same Push ID in multiple PUSH_PROMISE frames.  A client MUST
treat receipt of a PUSH_PROMISE that contains a larger Push ID than
the client has advertised or a Push ID which has already been
promised as a connection error of type HTTP_MALFORMED_FRAME.
Paragraph (version B):
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 frame that contains a larger Push ID
than the client has advertised as a connection error of
HTTP_ID_ERROR.
Paragraph (version B):
A server MUST NOT use the same Push ID in multiple PUSH_PROMISE
frames.  A client MUST treat receipt of a Push ID which has already
been promised as a connection error of type HTTP_ID_ERROR.
Paragraph (version A):
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 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 connection error
of type HTTP_MALFORMED_FRAME.
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 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 connection error
of type HTTP_ID_ERROR.
Paragraph (version A):
The DUPLICATE_PUSH frame carries a single variable-length integer
that identifies the Push ID of a resource that the server has
previously promised (see frame-push-promise), though that promise
might not be received before this frame.  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
DUPLICATE_PUSH that contains a larger Push ID than the client has
advertised as a connection error of type HTTP_MALFORMED_FRAME.
Paragraph (version B):
The DUPLICATE_PUSH frame carries a single variable-length integer
that identifies the Push ID of a resource that the server has
previously promised (see frame-push-promise), though that promise
might not be received before this frame.  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
DUPLICATE_PUSH that contains a larger Push ID than the client has
advertised as a connection error of type HTTP_ID_ERROR.
Paragraph (version A):
A Stream ID, Push ID, or Placeholder ID greater than the current
maximum for that identifier was referenced.
Paragraph (version A):
A Push ID was referenced in two different stream headers.
Paragraph (version B):
A Stream ID, Push ID, or Placeholder ID was used incorrectly, such
as exceeding a limit, reducing a limit, or being reused.