use std::sync::{atomic::AtomicBool, Arc};
use crate::{
app_system_error,
tina::{
data::AppResult,
server::session::{Session, SessionInner},
},
};
use super::request_ext::RequestExt;
impl Session {
pub async fn from_http_request<Req: RequestExt>(req: &Req) -> AppResult<Self> {
req.get_session().ok_or_else(|| app_system_error!("no Session found in request"))
}
pub async fn from_http_request_mut<Req: RequestExt>(req: &mut Req) -> AppResult<Self> {
let (session, is_new) = {
match req.get_session() {
None => {
let locale = Arc::new(req.get_locale());
let application = req.get_application()?;
let route_config = match req.get_route_config() {
Ok(v) => v,
Err(err) => return Err(err),
};
let request_time = req.get_request_time()?;
let enable_token = route_config.enable_token;
let security_config = application.get_security_config()?;
let token_key = security_config.token_header_name.as_str();
let token = req.get_request_header(token_key)?.map(|v| v.into_owned());
let session = Session::new(SessionInner {
application,
enable_token,
token,
locale,
request_time,
route_config: Some(route_config),
transaction_flag: AtomicBool::new(false),
extension: Default::default(),
attributes: Arc::new(Default::default()),
});
(session, true)
}
Some(session) => (session, false),
}
};
if is_new {
req.set_session(session.clone());
}
Ok(session)
}
}