From 165d1fb7863f93487eb78727794d8032aeb0cfea Mon Sep 17 00:00:00 2001 From: Erik Hollensbe Date: Thu, 17 Feb 2022 04:21:23 -0800 Subject: [PATCH] move logging and tls to separate features with optional deps; make logging a default feature Signed-off-by: Erik Hollensbe --- Cargo.toml | 10 ++++++-- src/app.rs | 71 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index aca3bf1..20c5e08 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,9 +13,15 @@ hyper = { version = "^0.14", features = [ "http1", "http2", "server", "runtime", http = "^0.2" async-recursion = "^1" tokio = { version = "^1", features = [ "full" ] } -tokio-rustls = "^0.23" -webpki = "^0.22" +tokio-rustls = { version = "^0.23", optional = true } +webpki = { version = "^0.22", optional = true } +log = { version = "^0.4", optional = true } [dev-dependencies] log = "^0.4" env_logger = "^0.9" + +[features] +default = ["logging"] +logging = ["log"] +tls = ["tokio-rustls", "webpki"] diff --git a/src/app.rs b/src/app.rs index 17e9699..94c3962 100644 --- a/src/app.rs +++ b/src/app.rs @@ -140,18 +140,45 @@ impl App< /// handler chain following the normal chain of responsibility rules described elsewhere. Only /// needed by server implementors. pub async fn dispatch(&self, req: Request) -> Result, Infallible> { + let _uri = req.uri().clone(); + let _method = req.method().clone(); + + #[cfg(feature = "logging")] + log::info!("{} request to {}", _method, _uri); + match self.router.dispatch(req, self.clone()).await { - Ok(resp) => Ok(resp), - Err(e) => match e.clone() { - Error::StatusCode(sc, msg) => Ok(Response::builder() - .status(sc) - .body(Body::from(msg)) - .unwrap()), - Error::InternalServerError(e) => Ok(Response::builder() - .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(Body::from(e.to_string())) - .unwrap()), - }, + Ok(resp) => { + let _status = resp.status().clone(); + + #[cfg(feature = "logging")] + log::info!( + "{} request to {}: responding with status {}", + _method, + _uri, + _status, + ); + + Ok(resp) + } + Err(e) => { + #[cfg(feature = "logging")] + log::error!( + "{} request to {}: responding with error {:?}", + _method, + _uri, + e, + ); + match e.clone() { + Error::StatusCode(sc, msg) => Ok(Response::builder() + .status(sc) + .body(Body::from(msg)) + .unwrap()), + Error::InternalServerError(e) => Ok(Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(Body::from(e.to_string())) + .unwrap()), + } + } } } @@ -167,13 +194,20 @@ impl App< let s = s.clone(); async move { s.clone().dispatch(req).await } }); - let (tcp_stream, _) = tcp_listener.accept().await?; + let (tcp_stream, _sa) = tcp_listener.accept().await?; + + #[cfg(feature = "logging")] + log::trace!("Request from {}", _sa,); + tokio::task::spawn(async move { if let Err(http_err) = Http::new() .http1_keep_alive(true) .serve_connection(tcp_stream, sfn) .await { + #[cfg(feature = "logging")] + log::error!("Error while serving HTTP connection: {}", http_err); + #[cfg(not(feature = "logging"))] eprintln!("Error while serving HTTP connection: {}", http_err); } }); @@ -182,6 +216,7 @@ impl App< /// Start a TLS-backed TCP/HTTP server with tokio. Performs dispatch on an as-needed basis. This is a more /// common path for users to start a server. + #[cfg(feature = "tls")] pub async fn serve_tls( self, addr: &str, @@ -197,7 +232,9 @@ impl App< let s = s.clone(); async move { s.clone().dispatch(req).await } }); - let (tcp_stream, _) = tcp_listener.accept().await?; + let (tcp_stream, _sa) = tcp_listener.accept().await?; + #[cfg(feature = "logging")] + log::trace!("Request from {}", _sa,); let config = config.clone(); tokio::task::spawn(async move { @@ -208,11 +245,17 @@ impl App< .serve_connection(tcp_stream, sfn) .await { + #[cfg(feature = "logging")] + log::error!("Error while serving HTTP connection: {}", http_err); + #[cfg(not(feature = "logging"))] eprintln!("Error while serving HTTP connection: {}", http_err); } } Err(e) => { - eprintln!("Error while serving TLS: {}", e) + #[cfg(feature = "logging")] + log::error!("Error while serving TLS: {:?}", e); + #[cfg(not(feature = "logging"))] + eprintln!("Error while serving TLS: {:?}", e); } } });