Skip to content

Support ResponseController read and write deadlines on HTTP/2 streams - #39

Merged
bogdanfinn merged 1 commit into
bogdanfinn:masterfrom
pagpeter:http2-stream-deadlines
Oct 27, 2026
Merged

bogdanfinn merged 1 commit into
bogdanfinn:masterfrom
pagpeter:http2-stream-deadlines

Conversation

@pagpeter

@pagpeter pagpeter commented Oct 26, 2026 •

Copy link
Copy Markdown

NewResponseController(w).SetReadDeadline and SetWriteDeadline return ErrNotSupported for HTTP/2, so a handler cannot bound how long it waits on one stream (for example a CONNECT tunnel whose peer stops reading) without a connection deadline that affects every stream.

This ports the per-stream deadlines from golang.org/x/net/http2 to http2/server.go and h2_bundle.go: the read-deadline timer, onReadTimeout and its stop on close from a870f352 (CL 446256), and SetReadDeadline, SetWriteDeadline and their serve-loop case from 93ec86b4 (CL 446335), unchanged. Not included: the per-stream Server.ReadTimeout and FlushError. Without x/net efda1ce1, a write that hits its deadline fails with http2: stream closed, not an error matching os.ErrDeadlineExceeded.

A write deadline resets the stream; that releases a write blocked on flow control thanks to #35, and cancels the handler's context thanks to #38.

Tests (h2_server_frames_test.go, both servers): a write blocked on a zero flow-control window must fail after its deadline and cancel the handler's context; read deadlines in the future and in the past must release a read of a body that never comes; and a read deadline on a request without a body must not panic (golang.org/issue/58237). Each fails without the corresponding server's change. go test ./... passes.

@bogdanfinn

Copy link
Copy Markdown
Owner

@pagpeter you can update the pr

NewResponseController(w).SetReadDeadline and SetWriteDeadline returned
ErrNotSupported for HTTP/2 requests, so a handler could not bound how long
it waits on a single stream, for example on a CONNECT tunnel whose peer
stops reading.

Port the per-stream deadlines from golang.org/x/net/http2 a870f352
(CL 446256) and 93ec86b4 (CL 446335) to http2 and to the bundled server
in h2_bundle.go. Server.ReadTimeout per stream and FlushError from those
changes are not included. Without x/net efda1ce1, also not included, a
write that hits its deadline fails with "http2: stream closed" rather
than an error matching os.ErrDeadlineExceeded.

A write deadline resets the stream. Releasing a write that is blocked on
flow control needs the RST_STREAM scheduling fix, and canceling the
handler's context needs closeStream to cancel it, so this builds on both.

The tests run against both servers: a write blocked on flow control, read
deadlines in the future and in the past, and a read deadline on a request
without a body (golang.org/issue/58237).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pagpeter
pagpeter force-pushed the http2-stream-deadlines branch from 2b24794 to a8ade0b Compare October 26, 2026 16:30
@pagpeter pagpeter changed the title Http2 stream deadlines Support ResponseController read and write deadlines on HTTP/2 streams Oct 26, 2026
@pagpeter
pagpeter marked this pull request as ready for review October 26, 2026 16:32
@bogdanfinn
bogdanfinn merged commit 89560c8 into bogdanfinn:master Oct 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants