diff --git a/Cargo.toml b/Cargo.toml index ce65222a..99eb40f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,6 +68,11 @@ thiserror = "1.0" # router path-tree = "0.7.4" +# session +sessions = "0.6" +sessions-core = "0.6" +sessions-memory = "0.6" + # http headers = "0.4" http = "1" diff --git a/examples/rustls/src/main.rs b/examples/rustls/src/main.rs index 66f18741..d0b26db3 100644 --- a/examples/rustls/src/main.rs +++ b/examples/rustls/src/main.rs @@ -16,7 +16,7 @@ async fn main() -> Result<()> { let app = Router::new().route("/", get(index)); - let listener = tls::Listener::<_, tls::rustls::TlsAcceptor>::new( + let listener = tls::TlsListener::<_, tls::rustls::TlsAcceptor>::new( listener, tls::rustls::Config::new() .cert(include_bytes!("../../tls/cert.pem").to_vec()) diff --git a/examples/session/Cargo.toml b/examples/session/Cargo.toml index a875f329..e9a03126 100644 --- a/examples/session/Cargo.toml +++ b/examples/session/Cargo.toml @@ -9,5 +9,5 @@ viz = { workspace = true, features = ["session"] } tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } -sessions = { version = "0.6.0", features = ["memory"] } +sessions = { workspace = true, features = ["memory"] } nano-id = "0.3" diff --git a/viz-core/Cargo.toml b/viz-core/Cargo.toml index 904cf799..897ac167 100644 --- a/viz-core/Cargo.toml +++ b/viz-core/Cargo.toml @@ -76,7 +76,7 @@ form-data = { version = "0.5.3", optional = true } serde = { workspace = true, features = ["derive"], optional = true } serde_json = { workspace = true, optional = true } serde_urlencoded = { workspace = true, optional = true } -sessions-core = { version = "0.6", optional = true } +sessions-core = { workspace = true, optional = true } # CSRF getrandom = { version = "0.2", optional = true } diff --git a/viz-test/Cargo.toml b/viz-test/Cargo.toml index 9b87517c..99f1f31a 100644 --- a/viz-test/Cargo.toml +++ b/viz-test/Cargo.toml @@ -24,7 +24,7 @@ http-body-util.workspace = true hyper.workspace = true mime.workspace = true serde.workspace = true -sessions = { version = "0.5", features = ["memory"] } +sessions = { workspace = true, features = ["memory"] } nano-id = "0.3" http = "=0.2" diff --git a/viz/src/lib.rs b/viz/src/lib.rs index 9b197794..2444960f 100644 --- a/viz/src/lib.rs +++ b/viz/src/lib.rs @@ -522,19 +522,19 @@ ))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -#[cfg(any(feature = "http1", feature = "http2"))] mod responder; -#[cfg(any(feature = "http1", feature = "http2"))] pub use responder::Responder; -#[cfg(any(feature = "http1", feature = "http2"))] + mod server; -#[cfg(any(feature = "http1", feature = "http2"))] -pub use server::{serve, Server}; +pub use server::{serve, Listener, Server}; /// TLS #[cfg(any(feature = "native_tls", feature = "rustls"))] pub mod tls; +pub use viz_core::*; +pub use viz_router::*; + #[cfg(feature = "handlers")] #[cfg_attr(docsrs, doc(cfg(feature = "handlers")))] #[doc(inline)] @@ -544,6 +544,3 @@ pub use viz_handlers as handlers; #[cfg_attr(docsrs, doc(cfg(feature = "macros")))] #[doc(inline)] pub use viz_macros::handler; - -pub use viz_core::*; -pub use viz_router::*; diff --git a/viz/src/server.rs b/viz/src/server.rs index 3845bb3b..6999db2d 100644 --- a/viz/src/server.rs +++ b/viz/src/server.rs @@ -11,10 +11,18 @@ use hyper_util::{ server::conn::auto::Builder, }; use tokio::{pin, select, sync::watch}; -use tokio_util::net::Listener; use crate::{future::FutureExt, Responder, Router, Tree}; +mod listener; +pub use listener::Listener; + +#[cfg(any(feature = "http1", feature = "http2"))] +mod tcp; + +#[cfg(all(unix, feature = "unix-socket"))] +mod unix; + /// Starts a server and serves the connections. pub fn serve(listener: L, router: Router) -> Server where @@ -77,7 +85,7 @@ where tree, signal, builder, - mut listener, + listener, } = self; let (shutdown_tx, shutdown_rx) = watch::channel(()); diff --git a/viz/src/server/listener.rs b/viz/src/server/listener.rs new file mode 100644 index 00000000..4b72e1eb --- /dev/null +++ b/viz/src/server/listener.rs @@ -0,0 +1,17 @@ +use std::{future::Future, io::Result}; + +use tokio::io::{AsyncRead, AsyncWrite}; + +/// A trait for a listener: `TcpListener` and `UnixListener`. +pub trait Listener { + /// The stream's type of this listener. + type Io: AsyncRead + AsyncWrite; + /// The socket address type of this listener. + type Addr; + + /// Accepts a new incoming connection from this listener. + fn accept(&self) -> impl Future> + Send; + + /// Returns the local address that this listener is bound to. + fn local_addr(&self) -> Result; +} diff --git a/viz/src/server/tcp.rs b/viz/src/server/tcp.rs new file mode 100644 index 00000000..83abd09e --- /dev/null +++ b/viz/src/server/tcp.rs @@ -0,0 +1,16 @@ +use std::{future::Future, io::Result, net::SocketAddr}; + +use tokio::net::{TcpListener, TcpStream}; + +impl super::Listener for TcpListener { + type Io = TcpStream; + type Addr = SocketAddr; + + fn accept(&self) -> impl Future> + Send { + TcpListener::accept(self) + } + + fn local_addr(&self) -> Result { + TcpListener::local_addr(self) + } +} diff --git a/viz/src/server/unix.rs b/viz/src/server/unix.rs new file mode 100644 index 00000000..2b1cff14 --- /dev/null +++ b/viz/src/server/unix.rs @@ -0,0 +1,16 @@ +use std::{future::Future, io::Result}; + +use tokio::net::{unix::SocketAddr, UnixListener, UnixStream}; + +impl super::Listener for UnixListener { + type Io = UnixStream; + type Addr = SocketAddr; + + fn accept(&self) -> impl Future> + Send { + UnixListener::accept(self) + } + + fn local_addr(&self) -> Result { + UnixListener::local_addr(self) + } +} diff --git a/viz/src/tls.rs b/viz/src/tls.rs index 7907ad36..0a53abcc 100644 --- a/viz/src/tls.rs +++ b/viz/src/tls.rs @@ -1,6 +1,6 @@ mod listener; -pub use listener::Listener; +pub use listener::TlsListener; /// `native_tls` #[cfg(feature = "native-tls")] diff --git a/viz/src/tls/listener.rs b/viz/src/tls/listener.rs index 7227d7c2..081d23a7 100644 --- a/viz/src/tls/listener.rs +++ b/viz/src/tls/listener.rs @@ -1,11 +1,11 @@ /// Unified TLS listener type. #[derive(Debug)] -pub struct Listener { +pub struct TlsListener { pub(crate) inner: T, pub(crate) acceptor: A, } -impl Listener { +impl TlsListener { /// Creates a new TLS listener. pub fn new(t: T, a: A) -> Self { Self { diff --git a/viz/src/tls/native_tls.rs b/viz/src/tls/native_tls.rs index bb5180ab..f727f661 100644 --- a/viz/src/tls/native_tls.rs +++ b/viz/src/tls/native_tls.rs @@ -1,15 +1,8 @@ -use std::{ - fmt, - io::{Error as IoError, ErrorKind, Result as IoResult}, - net::SocketAddr, - task::{Context, Poll}, -}; +use std::{fmt, io::Result as IoResult, net::SocketAddr}; -use futures_util::FutureExt; use tokio::net::{TcpListener, TcpStream}; use tokio_native_tls::{native_tls::TlsAcceptor as TlsAcceptorWrapper, TlsStream}; -use super::Listener; use crate::{Error, Result}; pub use tokio_native_tls::{native_tls::Identity, TlsAcceptor}; @@ -44,18 +37,18 @@ impl Config { } } -impl tokio_util::net::Listener for Listener { +impl crate::Listener for super::TlsListener { type Io = TlsStream; type Addr = SocketAddr; - fn poll_accept(&mut self, cx: &mut Context<'_>) -> Poll> { - let Poll::Ready((stream, addr)) = self.inner.poll_accept(cx)? else { - return Poll::Pending; - }; - Box::pin(self.acceptor.accept(stream)) - .poll_unpin(cx) - .map_ok(|stream| (stream, addr)) - .map_err(|e| IoError::new(ErrorKind::Other, e)) + async fn accept(&self) -> IoResult<(Self::Io, Self::Addr)> { + let (stream, addr) = self.inner.accept().await?; + let stream = self + .acceptor + .accept(stream) + .await + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?; + Ok((stream, addr)) } fn local_addr(&self) -> IoResult { diff --git a/viz/src/tls/rustls.rs b/viz/src/tls/rustls.rs index e9dd4c1c..3144bdd1 100644 --- a/viz/src/tls/rustls.rs +++ b/viz/src/tls/rustls.rs @@ -1,10 +1,8 @@ use std::{ io::{Error as IoError, ErrorKind, Result as IoResult}, net::SocketAddr, - task::{Context, Poll}, }; -use futures_util::FutureExt; use tokio::net::{TcpListener, TcpStream}; use tokio_rustls::{ rustls::{ @@ -16,7 +14,6 @@ use tokio_rustls::{ server::TlsStream, }; -use super::Listener; use crate::{Error, Result}; pub use tokio_rustls::TlsAcceptor; @@ -151,18 +148,14 @@ impl Config { } } -impl tokio_util::net::Listener for Listener { +impl crate::Listener for super::TlsListener { type Io = TlsStream; type Addr = SocketAddr; - fn poll_accept(&mut self, cx: &mut Context<'_>) -> Poll> { - let Poll::Ready((stream, addr)) = self.inner.poll_accept(cx)? else { - return Poll::Pending; - }; - self.acceptor - .accept(stream) - .poll_unpin(cx) - .map_ok(|stream| (stream, addr)) + async fn accept(&self) -> IoResult<(Self::Io, Self::Addr)> { + let (stream, addr) = self.inner.accept().await?; + let stream = self.acceptor.accept(stream).await?; + Ok((stream, addr)) } fn local_addr(&self) -> IoResult {