⚠️ Verification
🎯 Solution Description
Problem
In cases where HTTP/3 should behave like an optional enhancement, the current implementation can still fail hard or keep retrying a broken HTTP/3 path instead of gracefully staying on HTTP/2.
Current state
now fall back to http2 use the same req.body(but req.body is a pipe)
func (dt *dualTransport) RoundTrip(req *http.Request) (*http.Response, error) {
if cachedAltSvc.Protocol == "h3" {
resp, err := dt.http3Transport.RoundTrip(req)
if err == nil {
return resp, nil
}
// fallback to http2 with the same req
}
return dt.http2Transport.RoundTrip(req)
}
once the http3 transport starts reading from req.Body, part or all of the body may already have been consumed.
if http3 then fails and the code falls back to http2, http2 will reuse the same req.Body, which may now contain only the remaining data or may no longer be replayable at all.
what's more:
1.once the client caches an Alt-Svc entry for h3, it effectively does one thing: try HTTP/3 first on the next request.
2.If that attempt fails, it falls back to HTTP/2 for that request only.
3.It does not currently mark that HTTP/3 path unhealthy, evict the cached alternative, or apply any cooldown before trying it again.
4.As long as the cached entry is still valid, the next request can take the same HTTP/3-first path again.
5.If the HTTP/2 response keeps advertising the same Alt-Svc, that state gets refreshed, so a broken
QUIC path can keep being retried instead of being backed off explicitly.
Alt-Svc handling:
The parser can record alternative host and port, but the client still sends requests to the original authority, so the advertised alternative endpoints are not actually used.
Staleness handling is also incomplete: expired entries are ignored during lookup, but withdrawn alternatives are not explicitly cleaned up, and ma=0 is not treated as immediate invalidation.
now if http3 fail,use the same http.Request
📋 Use Cases
Fall back smoothly to HTTP/2 when HTTP/3 transport fails.
Apply explicit backoff and cooldown to unhealthy HTTP/3 paths to avoid immediate retries.
Make the alternative service addresses declared by Alt-Svc actually work.
The server only sends Alt-Svc when HTTP/3 is actually available.
Improve test coverage for the complete HTTP/3 upgrade and fallback flow.
⚖️ Complexity & Risks
No response
🔗 External Dependencies
No response
📘 Additional Context
No response
🎯 Solution Description
Problem
In cases where HTTP/3 should behave like an optional enhancement, the current implementation can still fail hard or keep retrying a broken HTTP/3 path instead of gracefully staying on HTTP/2.
Current state
now fall back to http2 use the same req.body(but req.body is a pipe)
once the http3 transport starts reading from req.Body, part or all of the body may already have been consumed.
if http3 then fails and the code falls back to http2, http2 will reuse the same req.Body, which may now contain only the remaining data or may no longer be replayable at all.
what's more:
1.once the client caches an
Alt-Svcentry forh3, it effectively does one thing: try HTTP/3 first on the next request.2.If that attempt fails, it falls back to HTTP/2 for that request only.
3.It does not currently mark that HTTP/3 path unhealthy, evict the cached alternative, or apply any cooldown before trying it again.
4.As long as the cached entry is still valid, the next request can take the same HTTP/3-first path again.
5.If the HTTP/2 response keeps advertising the same
Alt-Svc, that state gets refreshed, so a brokenQUIC path can keep being retried instead of being backed off explicitly.
Alt-Svchandling:The parser can record alternative host and port, but the client still sends requests to the original authority, so the advertised alternative endpoints are not actually used.
Staleness handling is also incomplete: expired entries are ignored during lookup, but withdrawn alternatives are not explicitly cleaned up, and ma=0 is not treated as immediate invalidation.
now if http3 fail,use the same http.Request
📋 Use Cases
Fall back smoothly to HTTP/2 when HTTP/3 transport fails.
Apply explicit backoff and cooldown to unhealthy HTTP/3 paths to avoid immediate retries.
Make the alternative service addresses declared by Alt-Svc actually work.
The server only sends Alt-Svc when HTTP/3 is actually available.
Improve test coverage for the complete HTTP/3 upgrade and fallback flow.
⚖️ Complexity & Risks
No response
🔗 External Dependencies
No response
📘 Additional Context
No response