From a57935c0399d5795525909d84b90281da8377950 Mon Sep 17 00:00:00 2001 From: Lukas Bergdoll Date: Thu, 14 Aug 2025 13:01:04 +0200 Subject: [PATCH] Generalize `Connected` implementation to all `Listener`s for `SocketAddr` (#3331) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: David Mládek --- axum/src/extract/connect_info.rs | 109 +++++++++++++++++++++++++------ 1 file changed, 88 insertions(+), 21 deletions(-) diff --git a/axum/src/extract/connect_info.rs b/axum/src/extract/connect_info.rs index c0d471d6..62dfb16f 100644 --- a/axum/src/extract/connect_info.rs +++ b/axum/src/extract/connect_info.rs @@ -30,12 +30,6 @@ pub struct IntoMakeServiceWithConnectInfo { _connect_info: PhantomData C>, } -#[test] -fn traits() { - use crate::test_helpers::*; - assert_send::>(); -} - impl IntoMakeServiceWithConnectInfo { pub(crate) fn new(svc: S) -> Self { Self { @@ -85,22 +79,13 @@ pub trait Connected: Clone + Send + Sync + 'static { #[cfg(all(feature = "tokio", any(feature = "http1", feature = "http2")))] const _: () = { use crate::serve; - use tokio::net::TcpListener; - impl Connected> for SocketAddr { - fn connect_info(stream: serve::IncomingStream<'_, TcpListener>) -> Self { - *stream.remote_addr() - } - } - - impl<'a, L, F> Connected>> for L::Addr + impl Connected> for SocketAddr where - L: serve::Listener, - L::Addr: Clone + Sync + 'static, - F: FnMut(&mut L::Io) + Send + 'static, + L: serve::Listener, { - fn connect_info(stream: serve::IncomingStream<'a, serve::TapIo>) -> Self { - stream.remote_addr().clone() + fn connect_info(stream: serve::IncomingStream<'_, L>) -> Self { + *stream.remote_addr() } } }; @@ -234,8 +219,90 @@ where #[cfg(test)] mod tests { use super::*; - use crate::{routing::get, serve::IncomingStream, test_helpers::TestClient, Router}; - use tokio::net::TcpListener; + use crate::{ + extract::connect_info::Connected, routing::get, serve::IncomingStream, serve::Listener, + test_helpers::TestClient, Router, + }; + use tokio::net::{TcpListener, TcpStream}; + + #[test] + fn into_make_service_traits() { + use crate::test_helpers::*; + assert_send::>(); + } + + #[allow(dead_code)] + #[allow(clippy::todo)] + fn connected_traits() { + // Test that the `Connected` trait can be used with custom address and listener types. + + fn create_router() -> Router { + todo!() + } + + fn tcp_listener() -> TcpListener { + todo!() + } + + #[derive(Clone)] + struct CustomAddr(SocketAddr); + + impl Connected> for CustomAddr { + fn connect_info(_stream: IncomingStream<'_, TcpListener>) -> Self { + todo!() + } + } + + impl Connected> for CustomAddr { + fn connect_info(_stream: IncomingStream<'_, CustomListener>) -> Self { + todo!() + } + } + + struct CustomListener {} + + impl Listener for CustomListener { + type Io = TcpStream; + type Addr = SocketAddr; + + async fn accept(&mut self) -> (Self::Io, Self::Addr) { + todo!() + } + + fn local_addr(&self) -> tokio::io::Result { + todo!() + } + } + + fn custom_connected() { + let router = create_router(); + let _ = crate::serve( + tcp_listener(), + router.into_make_service_with_connect_info::(), + ); + } + + fn custom_listener() { + let router = create_router(); + let _ = crate::serve(CustomListener {}, router.into_make_service()); + } + + fn custom_listener_with_connect() { + let router = create_router(); + let _ = crate::serve( + CustomListener {}, + router.into_make_service_with_connect_info::(), + ); + } + + fn custom_listener_with_custom_connect() { + let router = create_router(); + let _ = crate::serve( + CustomListener {}, + router.into_make_service_with_connect_info::(), + ); + } + } #[crate::test] async fn socket_addr() {