Skip to main content
ConnectInfo<T> is an extractor that provides access to connection information from the underlying transport.

Basic usage

To use ConnectInfo, your application must be served using into_make_service_with_connect_info:
use axum::{Router, routing::get, extract::ConnectInfo};
use std::net::SocketAddr;

async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {
    format!("Connected from: {}", addr)
}

let app = Router::new().route("/", get(handler));

// Use into_make_service_with_connect_info to enable ConnectInfo
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(
    listener,
    app.into_make_service_with_connect_info::<SocketAddr>()
).await.unwrap();
If you try to use ConnectInfo without into_make_service_with_connect_info, the extractor will fail at runtime with a missing extension error.

Custom connection info

You can provide custom connection information by implementing the Connected trait:
use axum::{
    Router,
    routing::get,
    extract::{connect_info::{ConnectInfo, Connected}, Request},
    serve::IncomingStream,
};
use tokio::net::TcpListener;

#[derive(Clone, Debug)]
struct MyConnectInfo {
    ip: String,
    user_agent: String,
}

impl Connected<IncomingStream<'_, TcpListener>> for MyConnectInfo {
    fn connect_info(_stream: IncomingStream<'_, TcpListener>) -> Self {
        Self {
            ip: "custom".to_string(),
            user_agent: "unknown".to_string(),
        }
    }
}

async fn handler(ConnectInfo(info): ConnectInfo<MyConnectInfo>) -> String {
    format!("IP: {}, UA: {}", info.ip, info.user_agent)
}

let app = Router::new().route("/", get(handler));

let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(
    listener,
    app.into_make_service_with_connect_info::<MyConnectInfo>()
).await.unwrap();

Testing with MockConnectInfo

For testing, use MockConnectInfo to avoid needing a real network connection:
use axum::{
    Router,
    routing::get,
    extract::connect_info::{ConnectInfo, MockConnectInfo},
};
use std::net::SocketAddr;

async fn handler(ConnectInfo(addr): ConnectInfo<SocketAddr>) -> String {
    format!("{}", addr)
}

let app = Router::new()
    .route("/", get(handler))
    .layer(MockConnectInfo(SocketAddr::from(([127, 0, 0, 1], 8080))));

// Now you can test without into_make_service_with_connect_info
If both MockConnectInfo and into_make_service_with_connect_info are used, the real connection info takes precedence.

Type signature

T
type parameter
The type of connection information to extract. Must implement Clone + Send + Sync + 'static.

Rejection

Rejects with MissingExtension if:
  • The application wasn’t started with into_make_service_with_connect_info
  • MockConnectInfo middleware wasn’t added

Common use cases

  • Rate limiting by IP: Track request rates per client IP address
  • Geolocation: Determine user location from IP for content personalization
  • Security logging: Record source IP for audit trails
  • Access control: Restrict endpoints based on client IP ranges

See also

  • State - Recommended way to share application state
  • Extension - For other request extensions