From 099edb8b1c9f68e1704d9129e388b2d91d301a17 Mon Sep 17 00:00:00 2001 From: holly sparkles Date: Wed, 7 Feb 2024 11:25:29 +0100 Subject: [PATCH] feat: support user-agent logging --- src/handler.rs | 25 ++++++++++++++++++++++--- src/server.rs | 5 +++++ src/settings/cli.rs | 12 ++++++++++++ src/settings/file.rs | 3 +++ src/settings/mod.rs | 5 +++++ src/testing.rs | 1 + 6 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/handler.rs b/src/handler.rs index 0106516..4711683 100644 --- a/src/handler.rs +++ b/src/handler.rs @@ -6,7 +6,7 @@ //! Request handler module intended to manage incoming HTTP requests. //! -use headers::{ContentType, HeaderMap, HeaderMapExt, HeaderValue}; +use headers::{ContentType, HeaderMap, HeaderMapExt, HeaderValue, UserAgent}; use hyper::{Body, Request, Response, StatusCode}; use std::{future::Future, net::IpAddr, net::SocketAddr, path::PathBuf, sync::Arc}; @@ -74,6 +74,8 @@ pub struct RequestHandlerOpts { pub index_files: Vec, /// Log remote address feature. pub log_remote_address: bool, + /// Log remote user agent feature. + pub log_remote_user_agent: bool, /// Redirect trailing slash feature. pub redirect_trailing_slash: bool, /// Ignore hidden files feature. @@ -121,6 +123,7 @@ impl RequestHandler { #[cfg(feature = "directory-listing")] let dir_listing_format = &self.opts.dir_listing_format; let log_remote_addr = self.opts.log_remote_address; + let log_remote_user_agent = self.opts.log_remote_user_agent; let redirect_trailing_slash = self.opts.redirect_trailing_slash; let compression_static = self.opts.compression_static; let ignore_hidden_files = self.opts.ignore_hidden_files; @@ -155,20 +158,36 @@ impl RequestHandler { } } + // Log request information with its remote user agent if available + let mut remote_user_agent_str = String::new(); + if log_remote_user_agent { + if let Some(client_user_agent) = headers + .get("User-Agent") + .and_then(|v| v.to_str().ok()) + .and_then(|s| s.split(',').next()) + .and_then(|s| s.trim().parse::().ok()) + { + remote_user_agent_str.push_str(" user_agent="); + remote_user_agent_str.push_str(&client_user_agent.to_string()) + } + } + // Health endpoint logs if health_request { tracing::debug!( - "incoming request: method={} uri={}{}", + "incoming request: method={} uri={}{}{}", method, uri, remote_addr_str, + remote_user_agent_str, ); } else { tracing::info!( - "incoming request: method={} uri={}{}", + "incoming request: method={} uri={}{}{}", method, uri, remote_addr_str, + remote_user_agent_str, ); } diff --git a/src/server.rs b/src/server.rs index a6b9674..b726f51 100644 --- a/src/server.rs +++ b/src/server.rs @@ -273,6 +273,10 @@ impl Server { let log_remote_address = general.log_remote_address; server_info!("log remote address: enabled={}", log_remote_address); + // Log remote user agent option + let log_remote_user_agent = general.log_remote_user_agent; + server_info!("log remote user-agent: enabled={}", log_remote_user_agent); + // Log redirect trailing slash option let redirect_trailing_slash = general.redirect_trailing_slash; server_info!( @@ -357,6 +361,7 @@ impl Server { #[cfg(feature = "basic-auth")] basic_auth, log_remote_address, + log_remote_user_agent, redirect_trailing_slash, ignore_hidden_files, index_files, diff --git a/src/settings/cli.rs b/src/settings/cli.rs index 60f912e..5b2fbdc 100644 --- a/src/settings/cli.rs +++ b/src/settings/cli.rs @@ -365,6 +365,18 @@ pub struct General { #[arg( long, + default_value = "false", + default_missing_value("true"), + num_args(0..=1), + require_equals(true), + action = clap::ArgAction::Set, + env = "SERVER_LOG_REMOTE_USER_AGENT", + )] + /// Log incoming requests information along with its remote user agent if available using the `info` log level. + pub log_remote_user_agent: bool, + + #[arg( + long, default_value = "true", default_missing_value("true"), num_args(0..=1), diff --git a/src/settings/file.rs b/src/settings/file.rs index 19e3bf0..c4a30cc 100644 --- a/src/settings/file.rs +++ b/src/settings/file.rs @@ -230,6 +230,9 @@ pub struct General { /// Log remote address feature. pub log_remote_address: Option, + /// Log remote user agent feature. + pub log_remote_user_agent: Option, + /// Redirect trailing slash feature. pub redirect_trailing_slash: Option, diff --git a/src/settings/mod.rs b/src/settings/mod.rs index 2114c91..a543fc5 100644 --- a/src/settings/mod.rs +++ b/src/settings/mod.rs @@ -145,6 +145,7 @@ impl Settings { let mut page_fallback = opts.page_fallback; let mut log_remote_address = opts.log_remote_address; + let mut log_remote_user_agent = opts.log_remote_user_agent; let mut redirect_trailing_slash = opts.redirect_trailing_slash; let mut ignore_hidden_files = opts.ignore_hidden_files; let mut index_files = opts.index_files; @@ -288,6 +289,9 @@ impl Settings { if let Some(v) = general.log_remote_address { log_remote_address = v } + if let Some(v) = general.log_remote_user_agent { + log_remote_user_agent = v + } if let Some(v) = general.redirect_trailing_slash { redirect_trailing_slash = v } @@ -550,6 +554,7 @@ impl Settings { #[cfg(feature = "fallback-page")] page_fallback, log_remote_address, + log_remote_user_agent, redirect_trailing_slash, ignore_hidden_files, index_files, diff --git a/src/testing.rs b/src/testing.rs index ef27a7e..b2b91b8 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -48,6 +48,7 @@ pub mod fixtures { #[cfg(feature = "basic-auth")] basic_auth: opts.general.basic_auth, log_remote_address: opts.general.log_remote_address, + log_remote_user_agent: opts.general.log_remote_user_agent, redirect_trailing_slash: opts.general.redirect_trailing_slash, ignore_hidden_files: opts.general.ignore_hidden_files, index_files: vec![opts.general.index_files], -- libgit2 1.7.2