Repository navigation
Conversation
djc
reviewed
Sep 23, 2026
djc
reviewed
Sep 24, 2026
into_inner() hands out the IO and the rustls connection of an established stream, but there was no way back. A caller who wants to swap the IO under a live TLS session, for instance to re-register a socket with another tokio runtime via TcpStream::into_std() and from_std(), or who completed the handshake outside this crate, had to keep the original TlsStream alive or reimplement the wrapper. The rustls connection carries all protocol state, including plaintext that was already decrypted but not yet read, so rebuilding the stream only needs the wrapper's own bookkeeping reset to "established": TlsState::Stream, no pending flush and no early-data waker. The constructor documents that the session must have completed its handshake and must not have been shut down, which is exactly what into_inner() of an established stream produces. Tests cover a round trip on both the client and the server side with plaintext left buffered in the session across the rebuild, and moving an established server stream to a runtime on another thread.
ctz
approved these changes
Sep 25, 2026
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.
Closes #138.
client::TlsStream::into_inner()andserver::TlsStream::into_inner()hand out theIOand the rustls connection of an established stream, but there was no constructor back.
This adds
from_parts(io, session)to both, taking the parts in the orderinto_inner()returns them.
Motivation (same as #138): moving an established TLS connection to another tokio runtime.
With plain TCP that is
TcpStream::into_std()+TcpStream::from_std(); with TLS it needsthe wrapper to be rebuilt around the re-registered socket. The other use in #138, a
handshake completed outside this crate, is covered by the same constructor.
Why this is safe: the rustls connection carries all protocol state, including plaintext
already decrypted but not yet read.
into_inner()only drops the wrapper's ownbookkeeping (
TlsState,need_flush, the early-data waker), which for an established,not shut down connection is always "Stream / no flush pending / no waker".
from_parts()resets it to exactly that and documents the requirement.
Tests:
from_parts_roundtrip: duplex pair; both sides are rebuilt, the server side with 8 bytesof a record still buffered in the session, which stay readable afterwards; clean
bidirectional close_notify.
from_parts_across_runtimes: server side is handshaken on the test runtime, detached withinto_std(), rebuilt withfrom_std()+from_parts()on a current_thread runtime onanother thread, and serves a request/response there.
Checked locally:
cargo test,cargo clippy --all-targetswith--deny warnings,cargo doc --document-private-itemswith-Dwarnings, rustfmt with the repo's 2024 styleconfig,
cargo check --libon 1.81 with the feature set the MSRV job uses (fips excludedlocally).