use hyper::Request;
use std::net::{IpAddr, SocketAddr};
use crate::{handler::RequestHandlerOpts, health};
pub(crate) fn init(enabled: bool, handler_opts: &mut RequestHandlerOpts) {
handler_opts.log_remote_address = enabled;
let trusted = if handler_opts.trusted_proxies.is_empty() {
"all".to_owned()
} else {
format!("{:?}", handler_opts.trusted_proxies)
};
tracing::info!("log requests with remote IP addresses: enabled={enabled}");
tracing::info!(
"log X-Real-IP header: enabled={}",
handler_opts.log_forwarded_for
);
tracing::info!(
"log X-Forwarded-For header: enabled={}",
handler_opts.log_forwarded_for
);
tracing::info!("trusted IPs for X-Forwarded-For: {trusted}");
}
pub(crate) fn pre_process<T>(
opts: &RequestHandlerOpts,
req: &Request<T>,
remote_addr: Option<SocketAddr>,
) {
let mut remote_addrs = String::new();
if opts.log_remote_address {
if let Some(addr) = remote_addr {
remote_addrs.push_str(format!(" remote_addr={addr}").as_str());
}
}
if opts.log_x_real_ip
&& (opts.trusted_proxies.is_empty()
|| remote_addr.is_some_and(|addr| opts.trusted_proxies.contains(&addr.ip())))
{
if let Some(real_ip) = req
.headers()
.get("X-Real-IP")
.and_then(|h| h.to_str().ok())
.and_then(|s| s.trim().parse::<IpAddr>().ok())
{
remote_addrs.push_str(format!(" x_real_ip={real_ip}").as_str());
}
}
if opts.log_forwarded_for
&& (opts.trusted_proxies.is_empty()
|| remote_addr.is_some_and(|addr| opts.trusted_proxies.contains(&addr.ip())))
{
if let Some(forwarded_for) = req
.headers()
.get("X-Forwarded-For")
.and_then(|h| h.to_str().ok())
.and_then(|s| s.split(',').next())
.and_then(|s| s.trim().parse::<IpAddr>().ok())
{
remote_addrs.push_str(format!(" real_remote_ip={forwarded_for}").as_str());
}
}
if opts.health && health::is_health_endpoint(req) {
tracing::debug!(
"incoming request: method={} uri={}{remote_addrs}",
req.method(),
req.uri(),
);
return;
}
tracing::info!(
"incoming request: method={} uri={}{remote_addrs}",
req.method(),
req.uri(),
);
}