A pit full of rusty nails
at main 48 lines 1.5 kB view raw
1use axum::http::HeaderValue; 2use hyper::{HeaderMap, header::FORWARDED}; 3use nailfv::{Parser, extract_for}; 4 5const X_REAL_IP: &str = "x-real-ip"; 6const X_FORWARDED_FOR: &str = "x-forwarded-for"; 7 8/// Tries to parse the `x-forwarded-for` header 9#[inline] 10pub fn maybe_x_forwarded_for(headers: &HeaderMap) -> Option<Box<str>> { 11 headers 12 .get(X_FORWARDED_FOR) 13 .and_then(header_value_to_str) 14 .and_then(|header| { 15 header 16 .split(',') 17 .map(str::trim) 18 .find_map(|header_parts| (!header_parts.is_empty()).then(|| header_parts.into())) 19 }) 20} 21 22/// Tries to parse the `x-real-ip` header 23#[inline] 24pub fn maybe_x_real_ip(headers: &HeaderMap) -> Option<Box<str>> { 25 headers 26 .get(X_REAL_IP) 27 .and_then(header_value_to_str) 28 .map(|header| header.trim().into()) 29} 30 31/// Tries to parse `forwarded` headers 32#[inline] 33pub fn maybe_forwarded_for(headers: &HeaderMap) -> Option<Box<str>> { 34 headers.get_all(FORWARDED).iter().find_map(|header| { 35 header_value_to_str(header).and_then(|header| { 36 header 37 .split(&[',', ';']) 38 .map(str::trim) 39 .filter(|&header_parts| !header_parts.is_empty()) 40 .find_map(|header_parts| extract_for.parse(header_parts).ok()) 41 }) 42 }) 43} 44 45#[inline] 46pub fn header_value_to_str(header_value: &HeaderValue) -> Option<&str> { 47 header_value.to_str().ok() 48}