From d30ac9c7aede4cbc6463ec1ee80b650b7bf9e9c7 Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 9 Nov 2026 04:09:09 +0000 Subject: api: a log line per HTTP request Requests weren't logged at all, short of what a handler logs itself. Now a middleware, outermost on the API (and on a relay-only node's), logs a line per request as web servers do: method and path (with the query), status, the milliseconds until the answer began (a stream goes on after), where it came from (the address, or `unix`), and the user (`-` where none was authenticated). The user comes back on the response: `basic_auth` puts it there, for a token as for a password or a trusted proxy's header. At debug, under the target `http` (`RUST_LOG=info,http=debug`, or `PUT /admin/log`): an open dashboard alone would fill the log at info. With the target off, the request passes untouched. --- src/api/auth.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'src/api/auth.rs') diff --git a/src/api/auth.rs b/src/api/auth.rs index ac70b82..f4806ca 100644 --- a/src/api/auth.rs +++ b/src/api/auth.rs @@ -211,7 +211,8 @@ fn parse_basic(headers: &HeaderMap) -> Option<(String, String)> { } /// The user a request authenticated as (a request extension, set by [`basic_auth`], or -/// by `login::bearer` for a token). +/// by `login::bearer` for a token; on the response too, for the request log, +/// `request_log`). #[derive(Clone, Debug)] pub(crate) struct AuthenticatedUser(pub(crate) String); @@ -293,8 +294,8 @@ pub(crate) async fn basic_auth( next: axum::middleware::Next, ) -> Response { // A token, taken already (`login::bearer`). - if request.extensions().get::().is_some() { - return next.run(request).await; + if let Some(user) = request.extensions().get::().cloned() { + return with_user(next.run(request).await, user); } let from = request .extensions() @@ -343,9 +344,17 @@ pub(crate) async fn basic_auth( }; }; - request.extensions_mut().insert(AuthenticatedUser(user)); + request + .extensions_mut() + .insert(AuthenticatedUser(user.clone())); request.extensions_mut().insert(via); - next.run(request).await + with_user(next.run(request).await, AuthenticatedUser(user)) +} + +/// `response`, naming the user it answered (`request_log`). +fn with_user(mut response: Response, user: AuthenticatedUser) -> Response { + response.extensions_mut().insert(user); + response } #[cfg(test)] -- cgit v1.3.1