diff --git a/src/request.rs b/src/request.rs index 4dca98043..a79b8e67e 100644 --- a/src/request.rs +++ b/src/request.rs @@ -4,6 +4,7 @@ use route_recognizer::Params; use std::ops::Index; use std::pin::Pin; +use std::sync::{Arc, RwLock}; #[cfg(feature = "cookies")] use crate::cookies::CookieData; @@ -500,10 +501,12 @@ impl Request { /// This method will panic if a tide::sessions:SessionMiddleware has not /// been run. #[cfg(feature = "sessions")] - pub fn session(&self) -> &crate::sessions::Session { - self.ext::().expect( + pub fn session(&self) -> std::sync::RwLockReadGuard<'_, crate::sessions::Session> { + let lock = self.ext::>>().expect( "request session not initialized, did you enable tide::sessions::SessionMiddleware?", - ) + ); + + lock.read().unwrap() } /// Retrieves a mutable reference to the current session. @@ -513,10 +516,12 @@ impl Request { /// This method will panic if a tide::sessions:SessionMiddleware has not /// been run. #[cfg(feature = "sessions")] - pub fn session_mut(&mut self) -> &mut crate::sessions::Session { - self.ext_mut().expect( + pub fn session_mut(&mut self) -> std::sync::RwLockWriteGuard<'_, crate::sessions::Session> { + let lock = self.ext::>>().expect( "request session not initialized, did you enable tide::sessions::SessionMiddleware?", - ) + ); + + lock.write().unwrap() } /// Get the length of the body stream, if it has been set. diff --git a/src/sessions/middleware.rs b/src/sessions/middleware.rs index 57dfbbd72..f9e2e7d4f 100644 --- a/src/sessions/middleware.rs +++ b/src/sessions/middleware.rs @@ -6,6 +6,8 @@ use crate::http::{ use crate::{utils::async_trait, Middleware, Next, Request}; use std::time::Duration; +use std::sync::{Arc, RwLock}; + use async_session::{ base64, hmac::{Hmac, Mac, NewMac}, @@ -86,16 +88,19 @@ where .and_then(|cookie| self.verify_signature(cookie.value()).ok()); let mut session = self.load_or_create(cookie_value).await; - if let Some(ttl) = self.session_ttl { session.expire_in(ttl); } let secure_cookie = request.url().scheme() == "https"; - request.set_ext(session.clone()); + + let session_lock = Arc::new(RwLock::new(session)); + request.set_ext(session_lock.clone()); let mut response = next.run(request).await; + let session = Arc::try_unwrap(session_lock).unwrap().into_inner().unwrap(); + if session.is_destroyed() { if let Err(e) = self.store.destroy_session(session).await { crate::log::error!("unable to destroy session", { error: e.to_string() });