You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.2 KiB

//! Contains info about the requester
use super::*;
use std::net::{
SocketAddr,
};
use std::{fmt,error};
use forwarded_list::XForwardedFor;
#[derive(Debug)]
pub struct Requester
{
source: Option<SocketAddr>,
x_forwarded_for: XForwardedFor,
}
pub use std::net::IpAddr;
impl Requester
{
pub fn new(source: Option<SocketAddr>, x_forwarded_for: XForwardedFor) -> Result<Self, NoIpError>
{
if source.is_none() && x_forwarded_for.addrs().len() == 0 {
Err(NoIpError)
} else {
Ok(Self{
source,
x_forwarded_for,
})
}
}
}
#[derive(Debug)]
pub struct NoIpError;
impl warp::reject::Reject for NoIpError{}
impl error::Error for NoIpError{}
impl fmt::Display for NoIpError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "no remote host IP address could be found")
}
}
/// Extract the IP using the specified settings for trusting the `X-Forwarded-For` header.
pub fn extract(trust_x: bool) -> impl Fn(Option<SocketAddr>, XForwardedFor) -> Result<IpAddr,NoIpError> + Clone
{
move |opt, x| {
if trust_x {
x.into_first().ok_or(NoIpError)
} else {
opt.map(|x| x.ip()).ok_or(NoIpError)
}
}
}