#![feature(impl_trait_in_assoc_type)]
use axum::{http::StatusCode, Router};
pub mod log;
pub fn use_zstd(router: Router) -> Router {
use tower_http::{
compression::{
predicate::{NotForContentType, Predicate, SizeAbove},
CompressionLayer,
},
CompressionLevel,
};
router.layer(
CompressionLayer::new()
.zstd(true)
.quality(CompressionLevel::Precise(16))
.compress_when(
SizeAbove::new(512)
.and(NotForContentType::GRPC)
.and(NotForContentType::IMAGES),
),
)
}
genv::def!(AXUM_TIMEOUT:u64 | 600);
pub fn use_timeout(router: Router) -> Router {
use axum::error_handling::HandleErrorLayer;
use tower::{BoxError, ServiceBuilder};
let middleware = ServiceBuilder::new()
.layer(HandleErrorLayer::new(|error: BoxError| async move {
if error.is::<tower::timeout::error::Elapsed>() {
Ok((StatusCode::REQUEST_TIMEOUT, "timeout"))
} else {
Err((
StatusCode::INTERNAL_SERVER_ERROR,
format!("Internal Error: {}", error),
))
}
}))
.layer(crate::log::Log)
.timeout(std::time::Duration::from_secs(AXUM_TIMEOUT()).into())
.layer(ServiceBuilder::new());
router.layer(middleware.into_inner())
}
pub fn layer(router: Router) -> Router {
let router = use_zstd(router);
let router = use_timeout(router);
router
}