use std::net::SocketAddr; use axum::extract::Request; use axum::response::Response; use imbl_value::json; use rpc_toolkit::Middleware; use serde::Deserialize; #[derive(Clone, Default)] pub struct ConnectInfo { peer_addr: Option, local_addr: Option, } impl ConnectInfo { pub fn new() -> Self { Self::default() } } #[derive(Deserialize)] pub struct Metadata { get_connect_info: bool, } impl Middleware for ConnectInfo { type Metadata = Metadata; async fn process_http_request( &mut self, _: &Context, request: &mut Request, ) -> Result<(), Response> { if let Some(axum::extract::ConnectInfo((peer, local))) = request.extensions().get().cloned() { self.peer_addr = Some(peer); self.local_addr = Some(local); } Ok(()) } async fn process_rpc_request( &mut self, _: &Context, metadata: Self::Metadata, request: &mut rpc_toolkit::RpcRequest, ) -> Result<(), rpc_toolkit::RpcResponse> { if metadata.get_connect_info { if let Some(peer_addr) = self.peer_addr { request.params["__ConnectInfo_peer_addr"] = json!(peer_addr); } if let Some(local_addr) = self.local_addr { request.params["__ConnectInfo_local_addr"] = json!(local_addr); } } Ok(()) } }