use std::net::SocketAddr;
use axum::extract::{ConnectInfo, FromRequestParts};
use axum::http::request::Parts;
use axum::response::Response;
use axum_client_ip::RightmostXForwardedFor;
use futures::future::BoxFuture;
use futures::FutureExt;
use crate::servers::http::v1::services::peer_ip_resolver::ClientIpSources;
pub struct Extract(pub ClientIpSources);
impl<S> FromRequestParts<S> for Extract
where
S: Send + Sync,
{
type Rejection = Response;
#[must_use]
fn from_request_parts<'life0, 'life1, 'async_trait>(
parts: &'life0 mut Parts,
state: &'life1 S,
) -> BoxFuture<'async_trait, Result<Self, Self::Rejection>>
where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
{
async {
let right_most_x_forwarded_for = match RightmostXForwardedFor::from_request_parts(parts, state).await {
Ok(right_most_x_forwarded_for) => Some(right_most_x_forwarded_for.0),
Err(_) => None,
};
let connection_info_ip = match ConnectInfo::<SocketAddr>::from_request_parts(parts, state).await {
Ok(connection_info_socket_addr) => Some(connection_info_socket_addr.0.ip()),
Err(_) => None,
};
Ok(Extract(ClientIpSources {
right_most_x_forwarded_for,
connection_info_ip,
}))
}
.boxed()
}
}