credence_lib/middleware/
catch.rs1use super::{constants::*, defer::*};
2
3use {
4 axum::{
5 extract::{Request, *},
6 http::*,
7 middleware::*,
8 response::{Response, *},
9 },
10 kutil_http::file::*,
11 std::{path::*, result::Result},
12};
13
14#[derive(Clone, Debug)]
23pub struct CatchMiddleware {
24 pub assets_path: PathBuf,
26}
27
28impl CatchMiddleware {
29 pub fn new(assets_path: PathBuf) -> Self {
31 Self { assets_path }
32 }
33
34 pub async fn function(
36 State(state_self): State<Self>,
37 request: Request,
38 next: Next,
39 ) -> Result<Response, StatusCode> {
40 if let Some(deferred_response) = DeferredResponse::get(&request) {
41 match deferred_response {
42 DeferredResponse::Hide => {
43 if let Some(response) = state_self.response(StatusCode::NOT_FOUND).await {
44 return Ok(response);
45 }
46 }
47
48 DeferredResponse::Authenticate(authenticate) => {
49 return Ok(DeferredResponse::authenticate(authenticate));
50 }
51
52 DeferredResponse::RedirectTo((uri_path, status_code)) => {
53 return Ok(DeferredResponse::redirect_to(uri_path, *status_code));
54 }
55
56 DeferredResponse::Error(message) => {
57 tracing::error!("{}", message);
58 if let Some(response) = state_self.response(StatusCode::INTERNAL_SERVER_ERROR).await {
59 return Ok(response);
60 }
61 }
62
63 _ => {}
64 }
65 }
66
67 let response = next.run(request).await;
68
69 let status = response.status();
70 if !status.is_success() {
71 if let Some(response) = state_self.response(status).await {
72 return Ok(response);
73 }
74 }
75
76 Ok(response)
77 }
78
79 pub async fn response(&self, status: StatusCode) -> Option<Response> {
81 let status = status.as_u16();
82 let file_path = self.assets_path.join(status.to_string() + HTML_SUFFIX);
83 if file_path.exists() {
84 tracing::debug!("status page: {}", status);
85 return Some(response_from_file(file_path).await.into_response());
86 }
87
88 None
89 }
90}