Skip to content

release: v0.8.2 - #315

Merged
iainmcgin merged 3 commits into
release-0.8from
release/v0.8.2
Sep 21, 2026
Merged

iainmcgin merged 3 commits into
release-0.8from
release/v0.8.2

Conversation

@iainmcgin

Copy link
Copy Markdown
Collaborator

Patch release for 0.8.1 carrying the fix from #313. A client- or bidi-streaming call can end while the client is still sending its request: the handler returns, an interceptor rejects the call, or the request timeout fires. The server kept reading the request body in a background task after that, so if a client stalled mid-message, that task, the partial message it had buffered and the HTTP/2 stream were held until the client ended the stream or closed the connection.

The reader now frees the partial message when the handler is gone and discards the rest of the body for at most 1 MiB and 5 seconds before dropping it. A client still uploading when the limit is reached loses its HTTP/2 stream or its HTTP/1.x connection.

It is cut from the v0.8.1 tag on a release-0.8 branch because main has unreleased API additions that do not belong in a patch. It enables tokio's macros feature in connectrpc, which 0.8.1 lacks and the reader's select! needs on wasm32; 0.9.0 already does. Unlike #313, the handler's request stream still ends when the drain does, not when the decoder finishes.

The companion crates stay at 0.8.0. After merge, a signed v0.8.2 tag runs release.yml and publish-crates.yml.

… is gone (backport)

The reader behind a client- or bidi-streaming call kept the partial message
it had buffered, its task and the request body until the client ended the
stream, even after the handler had returned, an interceptor had rejected the
call, or the request timeout had fired. A client that stalled part-way
through a message could hold them for as long as it kept the connection open.

The reader now races a body with nothing ready against the handler's end of
the request channel, so a gone handler is noticed while the client is
stalled. It frees the partial message and discards the rest of the body for
at most 1 MiB and 5 seconds (bytes only on wasm32, which has no clock), then
drops the body: an HTTP/2 stream is reset with NO_ERROR, an HTTP/1.x
connection is closed. The drain itself stays, on both versions: HTTP/1.x
needs it for keep-alive, and on HTTP/2 dropping the body at once makes h2
charge frames still in flight from the client to connection-wide budgets
and answer with GOAWAY(ENHANCE_YOUR_CALM). The end-to-end tests pin both.

Unlike main, the handler's request stream still ends with the drain rather
than when the decoder finishes; only the hold is bounded.

connectrpc now enables tokio's `macros` feature for the reader's `select!`,
as 0.9 already does.

Signed-off-by: Iain McGinniss <309153+iainmcgin@users.noreply.github.com>
…port)

hyper-util's auto connection reads until it can pick HTTP/1.1 or HTTP/2
and has no timer while it does, and hyper arms its header-read timeout
only after that. A peer that connected and sent nothing, or only part of
the HTTP/2 preface, therefore held its task and socket until it hung up,
even with the default 30 second timeout.

Wrap the accepted stream, in `Server` and in `axum::serve_tls`, so its
reads fail with `TimedOut` if the header-read timeout passes before the
peer has sent enough to pick HTTP/1.1 or HTTP/2 (the check hyper-util's
`ReadVersion` makes). After that the wrapper passes reads through and
hyper's timer takes over. An HTTP/2 connection that has sent its preface
is still not bounded by this timeout. A zero timeout, or one too long to
add to the clock, now disables both bounds instead of closing or
panicking every HTTP/1.1 connection.

Signed-off-by: Iain McGinniss <309153+iainmcgin@users.noreply.github.com>
Cuts the 0.8.2 patch release: `connectrpc` moves to 0.8.2 carrying two fixes
for connections that a stalled peer could hold open indefinitely: the request
body of a client- or bidi-streaming call that has already ended, and a
connection that sends nothing, or only part of the HTTP/2 preface, before the
header-read timeout applies. The companion crates are unchanged and stay at
their current versions; the publish workflow skips already-published
versions.

Cut from the v0.8.1 tag on a release branch rather than from main: main has
unreleased API additions that do not belong in a patch release.

After merge: signed v0.8.2 tag, which runs release.yml and publish-crates.yml.

Signed-off-by: Iain McGinniss <309153+iainmcgin@users.noreply.github.com>
@iainmcgin
iainmcgin requested a review from rpb-ant September 21, 2026 18:02
@iainmcgin
iainmcgin marked this pull request as ready for review September 21, 2026 18:02
@iainmcgin
iainmcgin merged commit 96dfc8e into release-0.8 Sep 21, 2026
1 check passed
@iainmcgin
iainmcgin deleted the release/v0.8.2 branch September 21, 2026 18:28
iainmcgin added a commit to allada/connect-rust that referenced this pull request Sep 24, 2026
Adds the `0.9.1` and `0.8.2` release notes, generated on the release
branches in connectrpc#314 and connectrpc#315, to main's `CHANGELOG.md` and `.changes/`, so
main's changelog lists every published release. Both versions are tagged
and on crates.io.

Signed-off-by: Iain McGinniss <309153+iainmcgin@users.noreply.github.com>
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