You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi! First of all, thanks for your open-source work!
I used aioquic HTTP3 on a server and decided to test it with rust h3-quinn implementation. To my surprise, I encountered a bug with POST requests as the server didn't correctly close the response body.
After some investigation, I pinpointed the cause to a grease frame which h3 crate sends in its stream finish method. It turns out that aioquic HTTP3 connection does not properly close the request stream where there are grease frames after request body. Instead, the library just hangs and awaits more data despite the fact the stream is closed.
Schematically, it can be described as so:
QUIC DATA FRAME (stream_id, [h3_headers, h3_body, h3_grease], stream_ended=True)
↓
> HTTP3 Connection
↓
H3 HeadersReceived(stream_ended=False)
H3 DataReceived(stream_ended=False)
# grease frame is ignored, but no even with stream_end=True is generated
Hope that makes sense :)
Initially, I wanted to submit a PR with a fix, but after diving into the code, I think the problem is more serious.
It turns out that this issue is the same for PUSH_PROMISE frames. If these frames are at the end of stream, the stream is not properly closed by aioquic. You can see here that the PUSH_PROMISE branch doesn't handle stream_ended argument similarly to how it's handled in HEADERS or DATA frames.
I though that adding something like this may be sufficient:
But it's not because the PUSH_PROMISE frame may be sent after the trailers, in which case we cannot return more DataReceived (I think, correct me If I'm wrong):
For me it seems like we need to introduce another HTTP3 Event to mark an explicit stream end in cases like these. It wouldn't be enough to add stream_ended=False to PushPromiseReceived because it will not work with grease frames:
Or, it should be handled by the users of the API and they should explicitly handle situation when QUIC frame ends a stream, but HTTP3 Connection didn't return any stream_ended marks. But it sounds awful to be honest :)
I've written a couple of test cases so you can check and debug the problem:
Hi! First of all, thanks for your open-source work!
I used aioquic HTTP3 on a server and decided to test it with rust
h3-quinn
implementation. To my surprise, I encountered a bug with POST requests as the server didn't correctly close the response body.After some investigation, I pinpointed the cause to a grease frame which
h3
crate sends in its stream finish method. It turns out that aioquic HTTP3 connection does not properly close the request stream where there are grease frames after request body. Instead, the library just hangs and awaits more data despite the fact the stream is closed.Schematically, it can be described as so:
Hope that makes sense :)
Initially, I wanted to submit a PR with a fix, but after diving into the code, I think the problem is more serious.
It turns out that this issue is the same for
PUSH_PROMISE
frames. If these frames are at the end of stream, the stream is not properly closed by aioquic. You can see here that the PUSH_PROMISE branch doesn't handlestream_ended
argument similarly to how it's handled inHEADERS
orDATA
frames.I though that adding something like this may be sufficient:
But it's not because the
PUSH_PROMISE
frame may be sent after the trailers, in which case we cannot return moreDataReceived
(I think, correct me If I'm wrong):For me it seems like we need to introduce another HTTP3 Event to mark an explicit stream end in cases like these. It wouldn't be enough to add
stream_ended=False
toPushPromiseReceived
because it will not work with grease frames:Or, it should be handled by the users of the API and they should explicitly handle situation when QUIC frame ends a stream, but HTTP3 Connection didn't return any
stream_ended
marks. But it sounds awful to be honest :)I've written a couple of test cases so you can check and debug the problem:
The text was updated successfully, but these errors were encountered: