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.
75 lines
1.2 KiB
75 lines
1.2 KiB
4 years ago
|
use std::{
|
||
|
net::{
|
||
|
IpAddr,
|
||
|
AddrParseError,
|
||
|
},
|
||
|
str,
|
||
|
error,
|
||
|
fmt,
|
||
|
};
|
||
|
|
||
|
#[derive(Debug)]
|
||
|
pub struct XFormatError;
|
||
|
|
||
|
impl error::Error for XFormatError{}
|
||
|
|
||
|
impl fmt::Display for XFormatError
|
||
|
{
|
||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||
|
{
|
||
|
write!(f, "X-Forwarded-For was not in the correct format")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Debug, Clone, PartialOrd, PartialEq, Eq, Default)]
|
||
|
pub struct XForwardedFor(Vec<IpAddr>);
|
||
|
|
||
|
impl XForwardedFor
|
||
|
{
|
||
|
pub fn new() -> Self
|
||
|
{
|
||
|
Self(Vec::new())
|
||
|
}
|
||
|
pub fn single(ip: impl Into<IpAddr>) -> Self
|
||
|
{
|
||
|
Self(vec![ip.into()])
|
||
|
}
|
||
|
pub fn addrs(&self) -> &[IpAddr]
|
||
|
{
|
||
|
&self.0[..]
|
||
|
}
|
||
|
|
||
|
pub fn into_first(self) -> Option<IpAddr>
|
||
|
{
|
||
|
self.0.into_iter().next()
|
||
|
}
|
||
|
|
||
|
pub fn into_addrs(self) -> Vec<IpAddr>
|
||
|
{
|
||
|
self.0
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl str::FromStr for XForwardedFor
|
||
|
{
|
||
|
type Err = XFormatError;
|
||
|
|
||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||
|
let mut output = Vec::new();
|
||
|
for next in s.split(',')
|
||
|
{
|
||
|
output.push(next.trim().parse()?)
|
||
|
}
|
||
|
Ok(Self(output))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl From<AddrParseError> for XFormatError
|
||
|
{
|
||
|
#[inline(always)] fn from(_: AddrParseError) -> Self
|
||
|
{
|
||
|
Self
|
||
|
}
|
||
|
}
|
||
|
|