Fix HTTP/3 large body handling - #385
Merged
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes HTTP/3 response stalls in Proxy Verifier by restoring QUIC flow-control credit when HTTP/3 DATA payload bytes are consumed by the application, ensuring large responses continue progressing beyond the initial receive window.
Changes:
- Pass
conn_user_datainto the HTTP/3 DATA receive callback and recover theH3Session*. - Extend QUIC stream- and connection-level receive windows by the consumed DATA payload size (
buflen) after appending it to the response body.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This was referenced May 29, 2026
bneradt
force-pushed
the
pv-h3-flow-control
branch
3 times, most recently
from
May 29, 2026 18:27
77e9031 to
dad8168
Compare
Large HTTP/3 replay bodies could stall after the initial send or receive windows were exhausted. Proxy Verifier consumed DATA but did not consistently drive QUIC flow-control, pacing, and timer work back into the egress path, so high-volume requests or responses could stop until the replay timed out. This returns consumed DATA credit to ngtcp2, treats QUIC timer wakeups separately from application read timeouts, resumes egress after ACKs drain the socket, and uses ngtcp2's nanosecond duration units for handshake and idle timers. This also updates the package version to 3.1.3 for the release that carries the fix. This expands the HTTP/3 AuTest to a 300 KB request and response body and compares small filtered transcripts instead of volatile, body-heavy async logs. That keeps the regression precise without making gold comparison expensive.
bneradt
force-pushed
the
pv-h3-flow-control
branch
from
May 29, 2026 19:17
dad8168 to
ff8f716
Compare
bneradt
pushed a commit
to bneradt/trafficserver
that referenced
this pull request
May 29, 2026
HTTP/3 over the quiche/BoringSSL path could stall or tear down under larger request and response bodies. Proxy Verifier now has coverage for body sizes that exceed initial flow-control windows, which exposed ATS leaving UDP bursts unread and consuming stream write data before quiche accepted it. This keeps QUIC stream write buffers pending until quiche reports bytes accepted, schedules packet writes when stream state changes, and keeps H3 transactions alive until request and response cleanup is safe. This also drains recvmmsg batches on edge-triggered UDP sockets so large bursts do not wait for an event that may never arrive. This adds replay coverage for H3 curl and Proxy Verifier scenarios, including multiple connections, large GET and POST bodies, and timeout and lifetime cleanup cases. The large-body Proxy Verifier test depends on yahoo/proxy-verifier#385.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Large HTTP/3 replay bodies could stall after the initial send or receive
windows were exhausted. Proxy Verifier consumed DATA but did not
consistently drive QUIC flow-control, pacing, and timer work back into
the egress path, so high-volume requests or responses could stop until
the replay timed out.
This returns consumed DATA credit to ngtcp2, treats QUIC timer wakeups
separately from application read timeouts, resumes egress after ACKs
drain the socket, and uses ngtcp2's nanosecond duration units for
handshake and idle timers. This also updates the package version to
3.1.3 for the release that carries the fix.
This expands the HTTP/3 AuTest to a 300 KB request and response body and
compares small filtered transcripts instead of volatile, body-heavy
async logs. That keeps the regression precise without making gold
comparison expensive.