lexa_framework/extract/
context.rs1use axum::http;
12
13use crate::http::{HttpContext, HttpContextInterface};
14use crate::state::State;
15
16#[derive(Debug)]
21#[derive(thiserror::Error)]
22#[error("\n\t{}: {0}", std::any::type_name::<Self>())]
23pub enum HttpContextError {
24 Extension(#[from] axum::extract::rejection::ExtensionRejection),
25 Infaillible(#[from] std::convert::Infallible),
26 MissingExtension,
27}
28
29#[axum::async_trait]
34impl<C, S> axum::extract::FromRequestParts<State<S>> for HttpContext<C>
35where
36 C: 'static,
37 C: HttpContextInterface,
38 S: 'static,
39 S: Send + Sync,
40 <C as HttpContextInterface>::State: Send + Sync,
41 <C as HttpContextInterface>::State: axum::extract::FromRef<State<S>>,
42{
43 type Rejection = HttpContextError;
44
45 async fn from_request_parts(
46 parts: &mut axum::http::request::Parts,
47 state: &State<S>,
48 ) -> Result<Self, Self::Rejection> {
49 let axum::extract::State(extracts) = axum::extract::State::<
51 <C as HttpContextInterface>::State,
52 >::from_request_parts(parts, state)
53 .await?;
54
55 let context = C::new(&parts.extensions, extracts)
56 .await
57 .ok_or(HttpContextError::MissingExtension)?
58 .shared();
59
60 let axum::extract::ConnectInfo(ip) =
62 axum::extract::ConnectInfo::from_request_parts(parts, state)
63 .await?;
64 let method = parts.method.clone();
65 let axum::extract::OriginalUri(uri) =
66 axum::extract::OriginalUri::from_request_parts(parts, state)
67 .await?;
68 let axum::extract::RawQuery(raw_query) =
69 axum::extract::RawQuery::from_request_parts(parts, state).await?;
70 let referer =
71 axum::TypedHeader::<axum::headers::Referer>::from_request_parts(
72 parts, state,
73 )
74 .await
75 .map(|ext| ext.0)
76 .ok();
77 let request = crate::http::HttpRequest {
78 context: context.clone(),
79 ip,
80 method,
81 uri,
82 raw_query,
83 referer,
84 };
85
86 let response = crate::http::HttpResponse {
88 context: context.clone(),
89 };
90
91 #[cfg(feature = "cookies")]
93 {
94 let cookie_key = state.cookie_key.as_ref().unwrap().clone();
95 let cookies_manager =
96 tower_cookies::Cookies::from_request_parts(parts, state)
97 .await
98 .expect("Cookies Manager");
99 let cookies =
100 crate::http::cookies::Cookies::new(cookies_manager, cookie_key);
101
102 let session = parts
103 .extensions
104 .get::<axum_sessions::SessionHandle>()
105 .cloned()
106 .map(|session_handle| {
107 crate::http::session::Session {
108 handle: session_handle,
109 }
110 })
111 .expect("Impossible d'extraire la session");
112
113 Ok(Self {
114 context,
115 request,
116 response,
117 cookies,
118 session,
119 })
120 }
121
122 #[cfg(not(feature = "cookies"))]
123 {
124 Ok(Self {
125 context,
126 request,
127 response,
128 })
129 }
130 }
131}
132
133impl axum::response::IntoResponse for HttpContextError {
134 fn into_response(self) -> axum::response::Response {
135 let err_status = http::StatusCode::INTERNAL_SERVER_ERROR;
136 let err_body = self.to_string();
137 (err_status, err_body).into_response()
138 }
139}