sword_layers/req_timeout/
layer.rs1use crate::{ResponseFnMapper, req_timeout::RequestTimeoutConfig};
2
3use axum::{
4 http::StatusCode,
5 response::{IntoResponse, Response},
6};
7
8use axum_responses::JsonResponse;
9use tower::{ServiceBuilder, util::MapResponseLayer};
10use tower_http::timeout::TimeoutLayer as TowerTimeoutLayer;
11use tower_layer::{Identity, Stack};
12
13type TimeoutLayerType = (
14 TowerTimeoutLayer,
15 ServiceBuilder<Stack<MapResponseLayer<ResponseFnMapper>, Identity>>,
16);
17
18pub struct RequestTimeoutLayer;
26
27impl RequestTimeoutLayer {
28 pub fn new(config: &RequestTimeoutConfig) -> TimeoutLayerType {
29 let layer = TowerTimeoutLayer::with_status_code(StatusCode::REQUEST_TIMEOUT, config.parsed);
30
31 fn timeout_mapper(response: Response) -> Response {
32 if response.status().as_u16() == 408 {
33 return JsonResponse::RequestTimeout().into_response();
34 }
35
36 response
37 }
38
39 let response_layer = ServiceBuilder::new().map_response(timeout_mapper as ResponseFnMapper);
40
41 (layer, response_layer)
42 }
43}