> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/tokio-rs/axum/llms.txt
> Use this file to discover all available pages before exploring further.

# ConnectInfo

> Extract connection metadata like IP addresses from client connections

`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`:

```rust theme={null}
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();
```

<Note>
  If you try to use `ConnectInfo` without `into_make_service_with_connect_info`, the extractor will fail at runtime with a missing extension error.
</Note>

## Custom connection info

You can provide custom connection information by implementing the `Connected` trait:

```rust theme={null}
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:

```rust theme={null}
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
```

<Info>
  If both `MockConnectInfo` and `into_make_service_with_connect_info` are used, the real connection info takes precedence.
</Info>

## Type signature

<ParamField path="T" type="type parameter">
  The type of connection information to extract. Must implement `Clone + Send + Sync + 'static`.
</ParamField>

## 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](/api/extractors/state) - Recommended way to share application state
* [Extension](/api/extractors/extension) - For other request extensions
