#[cfg(all(feature = "auth_jwt", feature = "with-db"))]
pub mod auth;
pub mod catch_panic;
pub mod compression;
pub mod cors;
pub mod etag;
pub mod fallback;
pub mod format;
pub mod limit_payload;
pub mod logger;
pub mod powered_by;
pub mod remote_ip;
pub mod request_id;
pub mod secure_headers;
pub mod static_assets;
pub mod timeout;
use axum::Router as AXRouter;
use limit_payload::LimitPayload;
use serde::{Deserialize, Serialize};
use crate::{app::AppContext, environment::Environment, Result};
pub trait MiddlewareLayer {
fn name(&self) -> &'static str;
fn is_enabled(&self) -> bool {
true
}
fn config(&self) -> serde_json::Result<serde_json::Value>;
fn apply(&self, app: AXRouter<AppContext>) -> Result<AXRouter<AppContext>>;
}
#[allow(clippy::unnecessary_lazy_evaluations)]
#[must_use]
pub fn default_middleware_stack(ctx: &AppContext) -> Vec<Box<dyn MiddlewareLayer>> {
let middlewares = &ctx.config.server.middlewares;
vec![
Box::new(
middlewares
.limit_payload
.clone()
.unwrap_or_else(|| LimitPayload {
enable: true,
..Default::default()
}),
),
Box::new(middlewares.cors.clone().unwrap_or_else(|| cors::Cors {
enable: true,
..Default::default()
})),
Box::new(
middlewares
.catch_panic
.clone()
.unwrap_or_else(|| catch_panic::CatchPanic { enable: true }),
),
Box::new(
middlewares
.etag
.clone()
.unwrap_or_else(|| etag::Etag { enable: true }),
),
Box::new(
middlewares
.remote_ip
.clone()
.unwrap_or_else(|| remote_ip::RemoteIpMiddleware {
enable: false,
..Default::default()
}),
),
Box::new(
middlewares
.compression
.clone()
.unwrap_or_else(|| compression::Compression { enable: false }),
),
Box::new(
middlewares
.timeout_request
.clone()
.unwrap_or_else(|| timeout::TimeOut {
enable: false,
..Default::default()
}),
),
Box::new(middlewares.static_assets.clone().unwrap_or_else(|| {
static_assets::StaticAssets {
enable: false,
..Default::default()
}
})),
Box::new(middlewares.secure_headers.clone().unwrap_or_else(|| {
secure_headers::SecureHeader {
enable: false,
..Default::default()
}
})),
Box::new(logger::new(
&middlewares
.logger
.clone()
.unwrap_or_else(|| logger::Config { enable: true }),
&ctx.environment,
)),
Box::new(
middlewares
.request_id
.clone()
.unwrap_or_else(|| request_id::RequestId { enable: true }),
),
Box::new(
middlewares
.fallback
.clone()
.unwrap_or_else(|| fallback::Fallback {
enable: ctx.environment != Environment::Production,
..Default::default()
}),
),
Box::new(powered_by::new(ctx.config.server.ident.as_deref())),
]
}
#[derive(Default, Debug, Clone, Deserialize, Serialize)]
pub struct Config {
pub compression: Option<compression::Compression>,
pub etag: Option<etag::Etag>,
pub limit_payload: Option<limit_payload::LimitPayload>,
pub logger: Option<logger::Config>,
pub catch_panic: Option<catch_panic::CatchPanic>,
pub timeout_request: Option<timeout::TimeOut>,
pub cors: Option<cors::Cors>,
#[serde(rename = "static")]
pub static_assets: Option<static_assets::StaticAssets>,
pub secure_headers: Option<secure_headers::SecureHeader>,
pub remote_ip: Option<remote_ip::RemoteIpMiddleware>,
pub fallback: Option<fallback::Fallback>,
pub request_id: Option<request_id::RequestId>,
}