From 7b034675b70d5b8e9282b50db2979a9a90a4d1cf Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 4 Jul 2025 13:47:13 -0400 Subject: [PATCH] feat(rt): introduce quic traits --- Cargo.toml | 3 +- src/rt/mod.rs | 4 +++ src/rt/quic.rs | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 src/rt/quic.rs diff --git a/Cargo.toml b/Cargo.toml index 3034cfeb57..a31b8813fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -101,7 +101,8 @@ nightly = [] level = "warn" check-cfg = [ 'cfg(hyper_unstable_tracing)', - 'cfg(hyper_unstable_ffi)' + 'cfg(hyper_unstable_ffi)', + 'cfg(hyper_unstable_quic)', ] [package.metadata.docs.rs] diff --git a/src/rt/mod.rs b/src/rt/mod.rs index 0eb266974f..d1b2f81792 100644 --- a/src/rt/mod.rs +++ b/src/rt/mod.rs @@ -17,6 +17,10 @@ pub mod bounds; mod io; mod timer; +#[cfg(hyper_unstable_quic)] +#[cfg_attr(docsrs, doc(cfg(hyper_unstable_quic)))] +pub mod quic; + pub use self::io::{Read, ReadBuf, ReadBufCursor, Write}; pub use self::timer::{Sleep, Timer}; diff --git a/src/rt/quic.rs b/src/rt/quic.rs new file mode 100644 index 0000000000..18271d34a8 --- /dev/null +++ b/src/rt/quic.rs @@ -0,0 +1,91 @@ +//! Generic QUIC support + +use std::pin::Pin; +use std::task::{Context, Poll}; + +use bytes::Buf; + +// TODO: Should this be gated by an `http3` feature? + +/// A QUIC connection. +pub trait Connection { + /// Send streams that can be opened by this connection. + type SendStream: SendStream; + /// Receive streams that can be accepted by this connection. + type RecvStream: RecvStream; + /// Bidirectional streams that can be opened or accepted by this connection. + type BidiStream: SendStream + RecvStream; + /// Errors that may occur opening or accepting streams. + type Error; + + // Accepting streams + + // Q: shorten to bidi? + /// Accept a bidirection stream. + fn poll_accept_bidirectional_stream( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll, Self::Error>>; + + /// Accept a unidirectional receive stream. + fn poll_accept_recv_stream( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll, Self::Error>>; + + // Creating streams + + // Q: shorten to bidi? + /// Open a bidirectional stream. + fn poll_open_bidirectional_stream( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>; + + /// Open a unidirectional send stream. + fn poll_open_send_stream( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll>; +} + +/// The send portion of a QUIC stream. +pub trait SendStream { + /// Errors that may happen trying to send data. + type Error; // bounds? + /// Polls that the stream is ready to send more data. + // Q: Should this be Pin<&mut Self>? + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll>; + /// Send data on the stream. + fn send_data(&mut self, data: B) -> Result<(), Self::Error>; + // fn poll_flush? + /// finish? + fn poll_finish(&mut self, cx: &mut Context<'_>) -> Poll>; + /// Close the stream with an error code. + fn reset(&mut self, reset_code: u64); +} + +/// The receive portion of a QUIC stream. +pub trait RecvStream { + /// Buffers of data that can be received. + type Buf: Buf; + /// Errors that may be received. + type Error; // bounds? + + // Q: should this be Pin? + /// Poll for more data received from the remote on this stream. + fn poll_data(&mut self, cx: &mut Context<'_>) -> Poll, Self::Error>>; + /// Signal to the remote peer to stop sending data. + fn stop_sending(&mut self, error_code: u64); +} + +/// An optional trait if a QUIC stream can be split into two sides. +pub trait BidiStream: SendStream + RecvStream { + /// The send side of a stream. + type SendStream: SendStream; + /// The receive side of a stream. + type RecvStream: RecvStream; + + /// Split this stream into two sides. + fn split(self) -> (Self::SendStream, Self::RecvStream); +}