refactor: unify error handling, graceful shutdown, and constants across framework

This commit is contained in:
2026-04-29 23:23:46 +02:00
committed by ForgeCode
parent db7b26864b
commit f37befacdd
14 changed files with 1990 additions and 182 deletions
+50 -7
View File
@@ -1,25 +1,36 @@
//! API Key authentication middleware.
//!
//! Validates requests by checking for a valid API key in the X-API-Key header.
use crate::{
Responder,
middleware::{Middleware, MiddlewareFuture, MiddlewareResult},
};
use http::Request;
use hyper::body::Incoming;
use http::{Request, Response};
use hyper::body::{Bytes, Incoming};
use log::warn;
/// Middleware that validates API key authentication via X-API-Key header.
pub struct ApiKeyMiddleware {
api_key: String,
}
impl ApiKeyMiddleware {
/// Creates a new ApiKeyMiddleware with the specified expected API key.
pub fn new(api_key: &str) -> Self {
Self {
api_key: api_key.to_string(),
}
}
/// Checks if the given API key is invalid.
pub fn is_invalid_key(&self, key: &str) -> bool {
key != self.api_key
}
}
impl Middleware for ApiKeyMiddleware {
fn run<'a>(&'a self, req: Request<Incoming>) -> MiddlewareFuture<'a> {
fn run(&self, req: Request<Incoming>) -> MiddlewareFuture<'_> {
let expected_key = self.api_key.clone();
Box::pin(async move {
@@ -28,15 +39,47 @@ impl Middleware for ApiKeyMiddleware {
if header == expected_key.as_str() {
MiddlewareResult::Continue(req)
} else {
warn!("X-API-Key wrong");
MiddlewareResult::Respond(Responder::unauthorized().unwrap())
warn!("X-API-Key validation failed for request");
// Return a default unauthorized response if Responder fails
let response = Responder::unauthorized()
.unwrap_or_else(|_| {
// Fallback to a basic unauthorized response
Response::builder()
.status(http::StatusCode::UNAUTHORIZED)
.body(http_body_util::Full::new(
Bytes::from("Unauthorized")
))
.expect("Failed to build fallback response")
});
MiddlewareResult::Respond(response)
}
}
None => {
warn!("X-API-Key missing");
MiddlewareResult::Respond(Responder::unauthorized().unwrap())
warn!("X-API-Key header missing from request");
let response = Responder::unauthorized()
.unwrap_or_else(|_| {
Response::builder()
.status(http::StatusCode::UNAUTHORIZED)
.body(http_body_util::Full::new(
Bytes::from("Unauthorized")
))
.expect("Failed to build fallback response")
});
MiddlewareResult::Respond(response)
}
}
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use http::Request;
#[test]
fn test_api_key_middleware_new() {
let middleware = ApiKeyMiddleware::new("test-key");
assert_eq!(middleware.api_key, "test-key");
}
}