use crate::{traits::MiddlewareTrait, Middleware};
use axum::{error_handling::HandleErrorLayer, http::StatusCode, response::IntoResponse};
use ayun_config::config;
use tower::{buffer::BufferLayer, limit::RateLimitLayer, ServiceBuilder};
pub struct RateLimit;
impl MiddlewareTrait for RateLimit {
fn handle() -> Middleware {
Box::new(|router| {
let config = config::<crate::config::Server>("server")?
.middleware
.rate_limit;
Ok(router.layer(
ServiceBuilder::new()
.layer(HandleErrorLayer::new(handle_error))
.layer(BufferLayer::new(config.buffer))
.layer(RateLimitLayer::new(
config.period,
std::time::Duration::from_millis(1000),
)),
))
})
}
}
async fn handle_error(error: axum::BoxError) -> axum::response::Response {
let message = format!("Unhandled internal error: {error}");
tracing::error!(err.msg = message, "error");
#[cfg(not(feature = "response-json"))]
{
(StatusCode::INTERNAL_SERVER_ERROR, message).into_response()
}
#[cfg(feature = "response-json")]
{
crate::response::json()
.code(StatusCode::INTERNAL_SERVER_ERROR)
.message(message)
.into_response()
}
}