mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-26 00:00:23 +02:00
Add extractor for remote connection info (#55)
Fixes https://github.com/tokio-rs/axum/issues/43 With this you can get the remote address like so: ```rust use axum::{prelude::*, extract::ConnectInfo}; use std::net::SocketAddr; let app = route("/", get(handler)); async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String { format!("Hello {}", addr) } // Starting the app with `into_make_service_with_connect_info` is required // for `ConnectInfo` to work. let make_svc = app.into_make_service_with_connect_info::<SocketAddr, _>(); hyper::Server::bind(&"0.0.0.0:3000".parse().unwrap()) .serve(make_svc) .await .expect("server failed"); ``` This API is fully generic and supports whatever transport layer you're using with Hyper. I've updated the unix domain socket example to extract `peer_creds` and `peer_addr`.
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
use axum::prelude::*;
|
||||
use axum::{
|
||||
extract::connect_info::{self, ConnectInfo},
|
||||
prelude::*,
|
||||
};
|
||||
use futures::ready;
|
||||
use http::{Method, StatusCode, Uri};
|
||||
use hyper::{
|
||||
@@ -9,9 +12,10 @@ use std::{
|
||||
io,
|
||||
path::PathBuf,
|
||||
pin::Pin,
|
||||
sync::Arc,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use tokio::net::UnixListener;
|
||||
use tokio::net::{unix::UCred, UnixListener};
|
||||
use tokio::{
|
||||
io::{AsyncRead, AsyncWrite},
|
||||
net::UnixStream,
|
||||
@@ -35,10 +39,10 @@ async fn main() {
|
||||
|
||||
let uds = UnixListener::bind(path.clone()).unwrap();
|
||||
tokio::spawn(async {
|
||||
let app = route("/", get(|| async { "Hello, World!" }));
|
||||
let app = route("/", get(handler));
|
||||
|
||||
hyper::Server::builder(ServerAccept { uds })
|
||||
.serve(app.into_make_service())
|
||||
.serve(app.into_make_service_with_connect_info::<UdsConnectInfo, _>())
|
||||
.await
|
||||
.unwrap();
|
||||
});
|
||||
@@ -67,6 +71,12 @@ async fn main() {
|
||||
assert_eq!(body, "Hello, World!");
|
||||
}
|
||||
|
||||
async fn handler(ConnectInfo(info): ConnectInfo<UdsConnectInfo>) -> &'static str {
|
||||
println!("new connection from `{:?}`", info);
|
||||
|
||||
"Hello, World!"
|
||||
}
|
||||
|
||||
struct ServerAccept {
|
||||
uds: UnixListener,
|
||||
}
|
||||
@@ -124,3 +134,23 @@ impl Connection for ClientConnection {
|
||||
Connected::new()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct UdsConnectInfo {
|
||||
peer_addr: Arc<tokio::net::unix::SocketAddr>,
|
||||
peer_cred: UCred,
|
||||
}
|
||||
|
||||
impl connect_info::Connected<&UnixStream> for UdsConnectInfo {
|
||||
type ConnectInfo = Self;
|
||||
|
||||
fn connect_info(target: &UnixStream) -> Self::ConnectInfo {
|
||||
let peer_addr = target.peer_addr().unwrap();
|
||||
let peer_cred = target.peer_cred().unwrap();
|
||||
|
||||
Self {
|
||||
peer_addr: Arc::new(peer_addr),
|
||||
peer_cred,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user