refactor: reuse not found macros

This commit is contained in:
xfy
2025-06-17 23:26:47 +08:00
parent 16bb3d33c8
commit 88098dca5c
2 changed files with 27 additions and 50 deletions

View File

@ -27,11 +27,18 @@ use super::{
}; };
macro_rules! custom_not_found { macro_rules! custom_not_found {
($host_config:expr, $request:expr) => {{ ($host_config:expr, $request:expr, $is_error_page:expr) => {{
let page = $host_config let page = if $is_error_page {
.not_found_page $host_config
.as_ref() .error_page
.ok_or(RouteError::RouteNotFound())?; .as_ref()
.ok_or(RouteError::RouteNotFound())?
} else {
$host_config
.not_found_page
.as_ref()
.ok_or(RouteError::RouteNotFound())?
};
let root = $host_config let root = $host_config
.root .root
.as_ref() .as_ref()
@ -65,7 +72,6 @@ macro_rules! custom_not_found {
} else { } else {
ReaderStream::new(file) ReaderStream::new(file)
}; };
let body = Body::from_stream(stream); let body = Body::from_stream(stream);
let mime = from_path(path).first_or_octet_stream(); let mime = from_path(path).first_or_octet_stream();
@ -132,7 +138,7 @@ pub async fn serve(
.ok_or(RouteError::RouteNotFound())?; .ok_or(RouteError::RouteNotFound())?;
tracing::debug!("proxy pass: {:?}", proxy_config); tracing::debug!("proxy pass: {:?}", proxy_config);
let Some(ref proxy_pass) = proxy_config.proxy_pass else { let Some(ref proxy_pass) = proxy_config.proxy_pass else {
return custom_not_found!(proxy_config, req); return custom_not_found!(proxy_config, req, true);
}; };
let uri = format!("{proxy_pass}{path_query}"); let uri = format!("{proxy_pass}{path_query}");
tracing::debug!("reverse proxy uri: {:?}", &uri); tracing::debug!("reverse proxy uri: {:?}", &uri);

View File

@ -36,12 +36,19 @@ use super::error::RouteResult;
/// # Arguments /// # Arguments
/// - `$host_route`: The route configuration containing `not_found_page` and `root` paths. /// - `$host_route`: The route configuration containing `not_found_page` and `root` paths.
macro_rules! custom_not_found { macro_rules! custom_not_found {
($host_route:expr, $request:expr) => { ($host_route:expr, $request:expr, $is_error_page:expr) => {
async { async {
let page = $host_route let page = if $is_error_page {
.not_found_page $host_route
.as_ref() .error_page
.ok_or(RouteError::RouteNotFound())?; .as_ref()
.ok_or(RouteError::RouteNotFound())?
} else {
$host_route
.not_found_page
.as_ref()
.ok_or(RouteError::RouteNotFound())?
};
let root = $host_route let root = $host_route
.root .root
.as_ref() .as_ref()
@ -61,42 +68,6 @@ macro_rules! custom_not_found {
}; };
} }
/// Macro to handle custom "error" responses for a route.
///
/// When an internal server error occurs, this macro:
/// 1. Checks if the `host_route` has a configured `error_page`.
/// 2. Attempts to serve the custom "error" file (e.g., `500.html`).
/// 3. Falls back to `InternalError` if the file is missing or unreadable.
///
/// # Arguments
/// - `$host_route`: The route configuration containing `error_page` and `root` paths.
/// - `$request`: The HTTP request object.
macro_rules! custom_error_page {
($host_route:expr, $request:expr) => {
async {
let page = $host_route
.error_page
.as_ref()
.ok_or(RouteError::InternalError())?;
let root = $host_route
.root
.as_ref()
.ok_or(RouteError::InternalError())?;
let path = format!("{}/{}", root, page.page);
let status = StatusCode::from_str(page.status.to_string().as_ref())
.map_err(|_| RouteError::BadRequest())?;
debug!("custom error path: {:?}", path);
match stream_file(path.into(), $request, Some(status)).await {
Ok(res) => RouteResult::Ok(res),
Err(e) => {
println!("Failed to stream file: {:?}", e);
RouteResult::Err(RouteError::InternalError())
}
}
}
};
}
/// Serve static files. /// Serve static files.
/// ///
/// This function handles requests for static files by: /// This function handles requests for static files by:
@ -151,7 +122,7 @@ pub async fn serve(
// check static file root configuration // check static file root configuration
// if root is None, then return InternalError // if root is None, then return InternalError
let Some(ref root) = host_route.root else { let Some(ref root) = host_route.root else {
return custom_not_found!(host_route, request).await; return custom_not_found!(host_route, request, true).await;
}; };
// try find index file first // try find index file first
// build index filename as vec // build index filename as vec
@ -183,7 +154,7 @@ pub async fn serve(
} }
let Some(path_exists) = path_exists else { let Some(path_exists) = path_exists else {
debug!("No valid file found in path candidates"); debug!("No valid file found in path candidates");
return custom_not_found!(host_route, request).await; return custom_not_found!(host_route, request, false).await;
}; };
match stream_file(path_exists.into(), request, None).await { match stream_file(path_exists.into(), request, None).await {
Ok(res) => Ok(res), Ok(res) => Ok(res),