Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
# 0.3.0
- added `set_expiration` to enable setting a different expiration from the one set in CookieOptions.
- `session.get_all` now returns a `Deserialize`able type `T` instead of `Hashmap<String, T>`

# 0.2.0
- specify `axum` and `redis-store` as optional features
- removed `insert_multiple`

# 0.1.11
- Initial Release
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "ruts"
description = "A middleware for tower sessions"
version = "0.2.0"
version = "0.3.0"
edition = "2021"
authors = ["Jimmie Lovell <[email protected]>"]
license = "MIT"
Expand Down
4 changes: 2 additions & 2 deletions src/extract/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ where
})?;

// Cookies are only used if the SessionLayer has a cookie_options set.
let cookie_options = &inner_session.cookie_options.ok_or_else(|| {
let cookie_name = inner_session.cookie_name.ok_or_else(|| {
tracing::error!("missing cookie options");
(StatusCode::INTERNAL_SERVER_ERROR, "missing cookie options")
})?;
Expand All @@ -44,7 +44,7 @@ where
let mut cookies = inner_session.cookies.lock();
*cookies = Some(cookies_ext.to_owned());

if let Some(cookie) = cookies.as_ref().unwrap().get(cookie_options.name) {
if let Some(cookie) = cookies.as_ref().unwrap().get(cookie_name) {
let session_id = cookie
.value()
.parse::<Id>()
Expand Down
52 changes: 30 additions & 22 deletions src/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ use cookie::time::Duration;
use pin_project_lite::pin_project;
use std::future::Future;
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::atomic::{AtomicBool, AtomicI64, Ordering};
use std::sync::Arc;
use std::task::{ready, Context, Poll};

/// A Tower Middleware to use `Session`.
#[derive(Clone, Debug)]
pub struct SessionService<S, T: SessionStore = RedisStore> {
inner: S,
cookie_options: Option<CookieOptions>,
cookie_options: Option<Arc<CookieOptions>>,
store: Arc<T>,
}

Expand All @@ -39,7 +39,7 @@ where
}
}

fn with_cookie_options(mut self, cookie_options: CookieOptions) -> Self {
fn with_cookie_options(mut self, cookie_options: Arc<CookieOptions>) -> Self {
self.cookie_options = Some(cookie_options);
self
}
Expand All @@ -60,10 +60,17 @@ where
}

fn call(&mut self, mut req: Request<ReqBody>) -> Self::Future {
let (cookie_name, cookie_max_age) = if let Some(cookie_options) = &self.cookie_options {
(Some(cookie_options.name), cookie_options.max_age)
} else {
(None, 0)
};

let inner_session = Inner {
id: RwLock::new(None),
cookies: Mutex::new(None),
cookie_options: Arc::new(self.cookie_options),
cookie_max_age: AtomicI64::new(cookie_max_age),
cookie_name,
store: Arc::clone(&self.store),
changed: AtomicBool::new(false),
deleted: AtomicBool::new(false),
Expand All @@ -74,6 +81,7 @@ where
ResponseFuture {
future: self.inner.call(req),
inner_session,
cookie_options: self.cookie_options.clone(),
}
}
}
Expand All @@ -95,14 +103,12 @@ where
/// .same_site(cookie::SameSite::Lax)
/// .secure(true)
/// .max_age(1 * 60)
/// .path("/");
///
/// let client = RedisClient::default();
/// // Initialize the client
///
/// let store = RedisStore::new(Arc::new(client));
/// let session_layer = SessionLayer::new(Arc::new(store))
/// .with_cookie_options(cookie_options);
/// .path("/");///
/// let client = RedisClient::default();
/// // Initialize the client///
/// let store = RedisStore::new(Arc::new(client));
/// let session_layer = SessionLayer::new(Arc::new(store))
/// .with_cookie_options(cookie_options);
/// ```
///
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -140,21 +146,22 @@ where
let service = SessionService::new(inner, self.store.clone());

if let Some(cookie_options) = self.cookie_options {
service.with_cookie_options(cookie_options)
service.with_cookie_options(Arc::new(cookie_options))
} else {
service
}
}
}

pin_project! {
/// Response future for SessionManager
#[derive(Debug)]
pub struct ResponseFuture<F, T: SessionStore> {
#[pin]
future: F,
inner_session: Arc<Inner<T>>,
}
/// Response future for SessionManager
#[derive(Debug)]
pub struct ResponseFuture<F, T: SessionStore> {
#[pin]
future: F,
inner_session: Arc<Inner<T>>,
cookie_options: Option<Arc<CookieOptions>>
}
}

impl<F, Body, E, T> Future for ResponseFuture<F, T>
Expand All @@ -167,17 +174,18 @@ where
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
let res = ready!(this.future.poll(cx)?);

let inner_session = this.inner_session;

if inner_session.deleted.load(Ordering::Relaxed) {
if let Some(cookie_options) = &*inner_session.cookie_options {
if let Some(cookie_options) = this.cookie_options {
if let Some(cookies) = inner_session.cookies.lock().as_ref() {
let cookie = Cookie::build(cookie_options.name);
cookies.remove(cookie.build());
}
}
} else if inner_session.changed.load(Ordering::Relaxed) {
if let Some(cookie_options) = &*inner_session.cookie_options {
if let Some(cookie_options) = this.cookie_options {
if let Some(cookies) = inner_session.cookies.lock().as_ref() {
if let Some(id) = inner_session.id.read().as_ref() {
build_cookie(id, cookie_options, cookies);
Expand Down
Loading