Implement IP header extraction

This commit is contained in:
Timo Ley 2022-01-08 19:01:19 +01:00
parent 8e5387600a
commit ac17b66a8d
5 changed files with 67 additions and 1 deletions

View file

@ -24,4 +24,5 @@ headers = "0.3.5"
url = {version = "2.2.2", features = ["serde"]}
askama = "0.10"
urlencoding = "2.1.0"
thiserror = "1.0.30"
thiserror = "1.0.30"
async-trait = "0.1.51"

28
src/lib/error.rs Normal file
View file

@ -0,0 +1,28 @@
use std::{convert::Infallible, net::AddrParseError};
use axum::{
body::{Bytes, Full},
response::IntoResponse,
};
use hyper::{header::ToStrError, StatusCode};
use thiserror::Error;
#[derive(Debug, Error)]
pub enum ExtractError {
#[error("`{0}` header is missing")]
HeaderMissing(String),
#[error("Header value contains illegal character: {0}")]
ToStr(#[from] ToStrError),
#[error("Header value is not a valid IP address: {0}")]
IPParse(#[from] AddrParseError),
}
impl IntoResponse for ExtractError {
type Body = Full<Bytes>;
type BodyError = Infallible;
fn into_response(self) -> hyper::Response<Self::Body> {
(StatusCode::BAD_REQUEST, self.to_string()).into_response()
}
}

32
src/lib/ipheader.rs Normal file
View file

@ -0,0 +1,32 @@
use std::{net::IpAddr, str::FromStr};
use async_trait::async_trait;
use axum::extract::{FromRequest, RequestParts};
use super::error::ExtractError;
pub struct ExtractIP(pub IpAddr);
#[async_trait]
impl<B> FromRequest<B> for ExtractIP
where
B: Send,
{
type Rejection = ExtractError;
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
let header = req
.headers()
.and_then(|headers| headers.get("x-forwarded-for"));
let header = header.ok_or(ExtractError::HeaderMissing("X-Forwarded-For".to_string()))?;
let mut value = header.to_str()?;
let pos = value.chars().position(|r| r == ',');
value = match pos {
Some(p) => &value[0..p],
None => value,
};
let ip = IpAddr::from_str(value)?;
Ok(Self(ip))
}
}

4
src/lib/mod.rs Normal file
View file

@ -0,0 +1,4 @@
mod error;
mod ipheader;
pub use ipheader::ExtractIP;

View file

@ -14,6 +14,7 @@ mod cdn;
mod config;
mod error;
mod ipfs;
mod lib;
mod v1;
#[derive(StructOpt)]