jiebi/CodeConvo huggingface dataset:
Change:
The transition to "Push Streams" has no preceding mention of server push. This adds a reference to the correct section of RFC7540.
If mention of server push is desired before mention of push stream, would it be simpler to move the final sentence of the paragraph to the start?
Maybe this would be better if section 4 was moved after section 6? Then the concepts would be explained before going into the framing. I'd also like to reorder/renumber all the push frame types so they're all adjacent to one another and in a sensible order. Is there a reason they're numbered as they are? If not, I'll open an issue to renumber them.
There's already an issue to reorder some of the sections, so I'm happy to consider this as part of the same discussion. As to the numbering, the primary reason is maintaining the same frame IDs for things that stayed over from HTTP/2 -- PUSHPROMISE has the same ID, CANCELPUSH has the ID that HTTP/2 used for RSTSTREAM, and DUPLICATEPUSH is brand new and so pushes into unallocated space.
Given that is in now, do you still see this as a problem?
I think the Server Push section still lacks a simple explanation of what the push does. A sentence like what I added in this PR at the beginning would help that. Currently the Server Push section goes directly into mechanics. URL "HTTP/3 server push is similar to what is described in HTTP/2 {{!HTTP2}}, but uses different mechanisms. Each server push is identified by a unique Push ID. ..." I'd add more to the first paragraph in case people don't want to read the H2 draft.
I think I'd prefer for the reference to be to 4.4 of the current draft instead, since that does point to RFC7540 and has more context as well.
Whoops -- which also doesn't have the two-sentence explanation of what push is. That's up in the intro. Let me copy that over to 4.4.
Thanks for the added text Mike, it looks great. I'm happy with this, so it's up to you to decide when this is ready to merge.

Discussion:
4.4. <del> HTTP/3 server push is similar to what is described in HTTP/2 HTTP2, but uses different mechanisms. </del> <ins> Server push is an interaction mode introduced in HTTP/2 HTTP2 which permits a server to push a request-response exchange to a client in anticipation of the client making the indicated request.  This trades off network usage against a potential latency gain.  HTTP/3 server push is similar to what is described in HTTP/2 HTTP2, but uses different mechanisms. </ins> Each server push is identified by a unique Push ID.  This Push ID is used in a single PUSH_PROMISE frame (see frame-push-promise) which

6.2.2. <ins> Server push is an optional feature introduced in HTTP/2 that allows a server to initiate a response before a request has been made.  See server-push for more details. </ins> A push stream is indicated by a stream type of "0x01", followed by the Push ID of the promise that it fulfills, encoded as a variable- length integer.  The remaining data on this stream consists of HTTP/3
Change:
This arises from a different discussion I had about the message exchange definition in section 5.1. The description is correct but glosses over the detail of QPACK, which is mentioned very briefly later in section 5.1.1. For complete accuracy, I would argue that a single message exchange may also contain one or more QPACK encoder instructions sent on the encoder stream.

Discussion:
PUSH_PROMISE frames are not part of the response; see server-push for more details. <ins> The HEADERS and PUSH_PROMISE frames might reference updates to the QPACK dynamic table.  While these updates are not directly part of the message exchange, they must be received and processed before the message can be consumed.  See header-formatting for more details. </ins> The "chunked" transfer encoding defined in Section 4.1 of RFC7230 MUST NOT be used.
Change:
Just in case it wasn't perfectly clear from the choice of words.
I know how you feel. We'll be defining "the" eventually. I don't know where the line is, but I think that it helps in this case to be doubly explicit.
I'm wondering how one could possibly misinterpret "abandoning" here. Furthermore, I don't think it's relevant for the server here if the client actually discarded the connection state, as long as it doesn't any more packets.
I don't think we need to spend a lot of energy here. I agree that this doesn't seem necessary, but I'm not going to fight it either.
The draft currently reads: "When a client receives a Version Negotiation packet, it MUST abandon the current connection attempt." However, it does not define what it is to abandon a connection attempt. Is it an abrupt termination without writing a connection close? That probably makes the most sense since the server is meant to be stateless at this stage.
Do we really need to define "abandon"? And if so, don't we need to define what "discarding" means?LGTM

Discussion:
versions without retaining state.  Though either the Initial packet or the Version Negotiation packet that is sent in response could be lost, the client will send new packets until it successfully receives <del> a response or it abandons the connection attempt. </del> <ins> a response or it abandons the connection attempt.  As a result, the client discards all state for the connection and does not send any more packets on the connection. </ins> A server MAY limit the number of Version Negotiation packets it sends.  For instance, a server that is able to recognize packets as
Change:
This should have been part of .
NAME I applied your suggestions. I think this PR should be marked as editorial.
The new "MUST" threw me, but it's not really new, is it?
That one was introduced in already.
Seems reasonable to me. Throughout here, should we be using "peer" or "receiver"? (The suggestions I make here are not issues with this change, but I'm sure that NAME or NAME will find them a home.)Thanks for fixing this.

Discussion:
endpoint's RTT samples, and rttvar is the endpoint's estimated variance in the RTT samples. <del> smoothed_rtt uses path latency after adjusting RTT samples for peer- reported host delays (host-delay).  A peer limits any delay in </del> <ins> The calculation of smoothed_rtt uses path latency after adjusting RTT samples for host delays (host-delay).  For packets sent in the ApplicationData packet number space, a peer limits any delay in </ins> sending an acknowledgement for an ack-eliciting packet to no greater <del> than the advertised max_ack_delay transport parameter.  Consequently, when a peer reports an Ack Delay that is greater than its max_ack_delay, the delay is attributed to reasons out of the peer's control, such as scheduler latency at the peer or loss of previous ACK frames.  Any delays beyond the peer's max_ack_delay are therefore considered effectively part of path delay and incorporated into the smoothed_rtt estimate. </del> <ins> than the value it advertised in the max_ack_delay transport parameter.  Consequently, when a peer reports an Ack Delay that is greater than its max_ack_delay, the delay is attributed to reasons out of the peer's control, such as scheduler latency at the peer or loss of previous ACK frames.  Any delays beyond the peer's max_ack_delay are therefore considered effectively part of path delay and incorporated into the smoothed_rtt estimate. </ins> When adjusting an RTT sample using peer-reported acknowledgement delays, an endpoint: <ins> MUST ignore the Ack Delay field of the ACK frame for packets sent in the Initial and Handshake packet number space. </ins> MUST use the lesser of the value reported in Ack Delay field of the ACK frame and the peer's max_ack_delay transport parameter (host-delay).
Change:
This still seems like a pointless restriction to me, but it's what we agreed in Tokyo, so here it is.
NAME I think I share the concern (though I am not sure how much I care). HTTP/3 is expected to allow extension frames to be used without coordination; this PR forbids that to happen on a stream that uses the CONNECT method.
S 5.2. Can you send anything other than DATA on a CONNECT stream? You don't say that I can't send anything else, but you don't say I can't either.
It doesn't mean anything (because we haven't assigned semantics), but we should probably just forbid the use of other frames (of those defined in this document). This is probably a shortcoming of 7540 as well.
Wouldn’t it be better to just prohibit the HEADERS frame? We might want to introduce a frame that changes a property of a stream (e.g., max bitrate). I do not think there’s a strong reason to forbid such kind of extensions only on CONNECT stream.
I don't want to prohibit extension frames, but the frames defined in the current spec don't serve any purpose. That is why I said "of those defined in this document".
Well, there's technically nothing preventing the use of push.... ;-) More seriously, I don't feel like the prohibition adds much. This maps the definition of the CONNECT method into H3 framing -- DATA frames == TCP payload. In any other respect, it's an HTTP request and frames mean what they otherwise mean. Is there a particular frame that needs to be prohibited? HEADERS would indicate a trailer block; it might be worth upstreaming to the updated semantic draft that a CONNECT tunnel can't have trailers.
Discussed in Tokyo; after the CONNECT takes effect, all frames other than DATA are prohibited unless an extension specifically provides otherwise.
nits

Discussion:
number of TCP segments is not guaranteed to map predictably to the size and number of HTTP DATA or QUIC STREAM frames. <ins> Once the CONNECT method has completed, only DATA frames are permitted to be sent on the stream.  Extension frames MAY be used if specifically permitted by the definition of the extension.  Receipt of any other frame type MUST be treated as a connection error of type HTTP_UNEXPECTED_FRAME. </ins> The TCP connection can be closed by either peer.  When the client ends the request stream (that is, the receive stream at the proxy enters the "Data Recvd" state), the proxy will set the FIN bit on its
Change:
I'm pretty sure the intent of URL was correct but the wrong error was changed in the draft. This pr makes the change that I think was intended in URL
Just a note. If this is the right answer and the PR lands, then will need to replace the new instance of HTTPMALFORMEDFRAME with something, e.g. HTTPINVALIDGOAWAY or something
Yeah, that crossed my mind. :-) YAEC!
In , NAME correctly observed that I messed up , but he closed his PR and I'm not able to reopen it without more git wizardry than I'm interested in practicing today. Easier just to fix it in my own branch.

Discussion:
QUIC Stream ID for a client-initiated bidirectional stream encoded as a variable-length integer.  A client MUST treat receipt of a GOAWAY frame containing a Stream ID of any other type as a connection error <del> of type HTTP_WRONG_STREAM. </del> <ins> of type HTTP_MALFORMED_FRAME. </ins> Clients do not need to send GOAWAY to initiate a graceful shutdown; they simply stop making new requests.  A server MUST treat receipt of

The GOAWAY frame applies to the connection, not a specific stream.  A client MUST treat a GOAWAY frame on a stream other than the control <del> stream as a connection error (errors) of type HTTP_UNEXPECTED_FRAME. </del> <ins> stream as a connection error (errors) of type HTTP_WRONG_STREAM. </ins> See connection-shutdown for more information on the use of the GOAWAY frame.
Change:
Receiving a HEADERS frame on a control stream should result in a connection error of type HTTPWRONGSTREAM. The correct error is documented for all other frame types except for HEADERS. This pr specifies the error for HEADERS frames as well.
This inconsistency was bugging me the other day. So thanks for beating me to fixing it :) NAME iff gets traction, we'd need a sweep of all these If a HEADERS frame is received on either control stream phrases to cover all streams (exclusively or inclusively).
NAME was closed. Is there anything else that's blocking this pr from being merged?
NAME I added NAME so he can review and merge this.

Discussion:
The HEADERS frame (type=0x1) is used to carry a header block, compressed using QPACK.  See QPACK for more details. <del> HEADERS frames can only be sent on request / push streams. </del> <ins> HEADERS frames can only be sent on request / push streams.  If a HEADERS frame is received on a control stream, the recipient MUST respond with a connection error (errors) of type HTTP_WRONG_STREAM. </ins> 7.2.3.
Change:
This pr changes the server's error on receipt of a PUSHPROMISE frame. While the current draft implicitly suggests push promises can only be sent by the server, it doesn't explicitly disallow clients from sending PUSHPROMISE frames. This pr explicitly disallows clients from sending PUSHPROMISE frames and requires the server to treat each receipt of a PUSHPROMISE frame as a connection error of type HTTPUNEXPECTEDFRAME.

Discussion:
the client has advertised or a Push ID which has already been promised as a connection error of type HTTP_MALFORMED_FRAME. <del> If a PUSH_PROMISE frame is received on either control stream, the recipient MUST respond with a connection error (errors) of type </del> <ins> If a PUSH_PROMISE frame is received on the control stream, the client MUST respond with a connection error (errors) of type </ins> HTTP_WRONG_STREAM. <ins> A client MUST NOT send a PUSH_PROMISE frame.  A server MUST treat the receipt of a PUSH_PROMISE frame as a connection error of type HTTP_UNEXPECTED_FRAME. </ins> See server-push for a description of the overall server push mechanism.
Change:
by clearly splitting the two different error cases.
Moves existing text to be clearer, but doesn't change the stated requirements. Editorial, and fine by me.
It's unclear which error should be reported if an endpoint receives a second SETTINGS frame on any stream that's not a control stream. Perhaps this should be explicitly defined in the draft?
Hey NAME I initially thought this was an editorial problem so created as an attempt to clarify things. However, I think the question is more philosophical. To analyse it a bit, what you're asking is how to handle an error after the occurrence of a critical connection error. First, a SETTINGS frame on a wrong stream type, then another SETTINGS frame on a wrong stream. After the first critical error, all bets are off. I'd expect a lot implementations to just give up at that stage as the peer is likely to be misbehaving.
I agree its an edge case but I do think it'd be useful to exactly specify which of the two errors should be reported, especially when thinking of automated testing of HTTP/3 implementations.
I'm sympathetic to that but I fear this could be a slippery slope towards adding lots of text for issues that occur after a critical close event. PRIORITY frames fall into a similar bucket, along with many of the server push frames and their validation rules.
I think the real unclarity in the spec is that both can happen simultaneously. After receiving a proper SETTINGS frame on the control channel, receiving a SETTINGS frame on some other stream would be both a second SETTINGS frame and a SETTINGS frame on the wrong stream. clarifies this reasonable. Thanks, both of you!

Discussion:
SETTINGS frames always apply to a connection, never a single stream. A SETTINGS frame MUST be sent as the first frame of each control stream (see control-streams) by each peer, and MUST NOT be sent <del> subsequently or on any other stream.  If an endpoint receives a SETTINGS frame on a different stream, the endpoint MUST respond with a connection error of type HTTP_WRONG_STREAM.  If an endpoint receives a second SETTINGS frame, the endpoint MUST respond with a connection error of type HTTP_UNEXPECTED_FRAME. </del> <ins> subsequently.  If an endpoint receives a second SETTINGS frame on the control stream, the endpoint MUST respond with a connection error of type HTTP_UNEXPECTED_FRAME. SETTINGS frames MUST NOT be sent on any steam other than the control stream.  If an endpoint receives a SETTINGS frame on a different stream, the endpoint MUST respond with a connection error of type HTTP_WRONG_STREAM. </ins> SETTINGS parameters are not negotiated; they describe characteristics of the sending peer, which can be used by the receiving peer.
Change:
reincarnated, because I messed up. Sorry, NAME
LGTM but don't forget push

Discussion:
The "chunked" transfer encoding defined in Section 4.1 of RFC7230 MUST NOT be used. <ins> If a DATA frame is received before a HEADERS frame on a either a request or push stream, the recipient MUST respond with a connection error of type HTTP_UNEXPECTED_FRAME (errors). </ins> Trailing header fields are carried in an additional HEADERS frame following the body.  Senders MUST send only one HEADERS frame in the trailers section; receivers MUST discard any subsequent HEADERS
Change:
TBH I'm not sure the whole "set GOAWAY last stream id to MAXSTREAMID / maximum value allowed by MAX_STREAMS" is really necessary, but I kept it for now.

Discussion:
this connection, while requests on the indicated stream ID and greater were rejected.  This enables client and server to agree on which requests were accepted prior to the connection shutdown.  This <del> identifier MAY be lower than the stream limit identified by a QUIC MAX_STREAM_ID frame, and MAY be zero if no requests were processed. Servers SHOULD NOT increase the QUIC MAX_STREAM_ID limit after sending a GOAWAY frame. </del> <ins> identifier MAY be zero if no requests were processed.  Servers SHOULD NOT increase the QUIC MAX_STREAMS limit after sending a GOAWAY frame. </ins> Clients MUST NOT send new requests on the connection after receiving GOAWAY; a new connection MAY be established to send additional

might already have retried unprocessed requests on another connection.  A server that is attempting to gracefully shut down a connection SHOULD send an initial GOAWAY frame with the last Stream <del> ID set to the current value of QUIC's MAX_STREAM_ID and SHOULD NOT increase the MAX_STREAM_ID thereafter.  This signals to the client that a shutdown is imminent and that initiating further requests is prohibited.  After allowing time for any in-flight requests (at least one round-trip time), the server MAY send another GOAWAY frame with an updated last Stream ID.  This ensures that a connection can be cleanly shut down without losing requests. </del> <ins> ID set to the maximum value allowed by QUIC's MAX_STREAMS and SHOULD NOT increase the MAX_STREAMS limit thereafter.  This signals to the client that a shutdown is imminent and that initiating further requests is prohibited.  After allowing time for any in-flight requests (at least one round-trip time), the server MAY send another GOAWAY frame with an updated last Stream ID.  This ensures that a connection can be cleanly shut down without losing requests. </ins> Once all accepted requests have been processed, the server can permit the connection to become idle, or MAY initiate an immediate closure
Change:
Until now, only bidirectional streams were specified to treat a truncated last frame on a cleanly terminated stream as an error. With this pr, the same logic applies to push streams as well. I just slightly reworded the text from the bidirectional streams section and put it into the push stream section. Not sure if this is the best solution but I'm also not sure where to put the text if the text for both the bidirectional streams and push streams had to be combined.
already contains this text: That's intended to cover any stream type with frames. Perhaps we should consolidate the language from both sections into that, possibly leaving behind cross-references.
I hadn't seen that paragraph yet. I'd propose to drop the text in the Bidirectional Streams section. The reasoning is that when searching for what to do when a stream is closed with a truncated frame, I found (or rather was pointed to) the text in the Bidirectional Streams section. After finding a paragraph like that, I didn't expect to find any other text in the rfc related to truncated frames (which led to this pr). Without the text in the Bidirectional Streams section, I might have found the text in the Frame Layout section first which would have immediately answered my question. This would also consolidate errors related to frames in the HTTP Framing Layer section which seems like the first place to go looking for frame related errors. Should I make another pr (if this sounds like a good idea) or update this one with the proposed change?
Fine to just update this one. Thanks!
This is the best I could come up with. I had to relax the text from Frame Layout to allow truncated frames on abruptly closed streams. Maybe abruptly closed stream should be clarified better (I'm not sure if this is done elsewhere already?).
Reworded so as to not change the original text as much. The pr now just moves the truncation section from the streams section to the frames section.

Discussion:
It is recommended that "initial_max_bidi_streams" be no smaller than 100, so as to not unnecessarily limit parallelism. <del> These streams carry frames related to the request/response (see request-response).  When a stream terminates cleanly, if the last frame on the stream was truncated, this MUST be treated as a connection error (see HTTP_MALFORMED_FRAME in http-error-codes). Streams which terminate abruptly may be reset at any point in the frame. </del> HTTP/3 does not use server-initiated bidirectional streams; clients MUST omit or specify a value of zero for the QUIC transport parameter "initial_max_bidi_streams".

the end of the identified fields MUST be treated as a connection error of type HTTP_MALFORMED_FRAME. <ins> When a stream terminates cleanly, if the last frame on the stream was truncated, this MUST be treated as a connection error (errors) of type HTTP_MALFORMED_FRAME.  Streams which terminate abruptly may be reset at any point in a frame. </ins> 7.2. 7.2.1.
Change:
Reword the text to be a bit more clear about what's expected from a CID issuer.
I believe this is editorial, since it does not change any normative text.
This inverts the form of the recommendation, but doesn't really change the design.
We previously had text: In adding text for the TP (activeconnectionid_limit), we kept the same idea, but lost a little bit of the text: We still need the SHOULD replace used CIDs in the event that we haven't provided the peer with the maximum number of CIDs.
Putting together a PR for this

Discussion:
An endpoint SHOULD ensure that its peer has a sufficient number of available and unused connection IDs.  Endpoints store received <del> connection IDs for future use.  An endpoint uses the active_connection_id_limit transport parameter to advertise the number of connection IDs it can store for future use.  An endpoint SHOULD NOT provide more connection IDs than the peer's limit.  If an endpoint has provided its peer with the maximum number of connection IDs, it SHOULD only provide a new connection ID when the peer retires one.  An endpoint MAY limit the frequency or the total number of connection IDs issued for each connection to avoid the risk of running out of connection IDs (see reset-token). </del> <ins> connection IDs for future use and advertise the number of connection IDs they are willing to store with the active_connection_id_limit transport parameter.  An endpoint SHOULD NOT provide more connection IDs than the peer's limit. An endpoint SHOULD supply a new connection ID when it receives a packet with a previously unused connection ID or when the peer retires one, unless providing the new connection ID would exceed the peer's limit.  An endpoint MAY limit the frequency or the total number of connection IDs issued for each connection to avoid the risk of running out of connection IDs; see reset-token. </ins> An endpoint that initiates migration and requires non-zero-length connection IDs SHOULD ensure that the pool of connection IDs