Skip to content

Commit cac9880

Browse files
committed
pass session data to storage provider when deleting
this helps with keeping session index up to date
1 parent 26c5246 commit cac9880

9 files changed

Lines changed: 34 additions & 42 deletions

File tree

src/fairing.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,21 @@ struct MySession {
3535
#[rocket::launch]
3636
fn rocket() -> _ {
3737
// Use default settings with in-memory storage
38-
let session_fairing = RocketFlexSession::<MySession>::default();
38+
let default_fairing = RocketFlexSession::<MySession>::default();
3939
4040
// Or customize settings with the builder
41-
let custom_session = RocketFlexSession::<MySession>::builder()
42-
.storage(CookieStorage::default()) // or a custom storage provider
41+
let my_fairing = RocketFlexSession::<MySession>::builder()
42+
.storage(CookieStorage::default())
4343
.with_options(|opt| {
4444
opt.cookie_name = "my_cookie".to_string();
4545
opt.path = "/app".to_string();
46-
opt.max_age = 7 * 24 * 60 * 60; // 7 days
46+
opt.max_age = 7 * 24 * 60 * 60;
4747
})
4848
.build();
4949
5050
rocket::build()
51-
.attach(session_fairing)
51+
.attach(default_fairing)
52+
.attach(my_fairing)
5253
// ... other configuration ...
5354
}
5455
```
@@ -131,19 +132,19 @@ where
131132
let (updated, deleted) = session_inner.lock().unwrap().take_for_storage();
132133

133134
// Handle deleted session
134-
if let Some(deleted_id) = deleted {
135-
rocket::debug!("Found deleted session. Deleting session '{deleted_id}'...");
136-
if let Err(e) = self.storage.delete(&deleted_id, req.cookies()).await {
137-
rocket::warn!("Error while deleting session '{deleted_id}': {e}");
135+
if let Some((id, data)) = deleted {
136+
rocket::debug!("Found deleted session. Deleting session '{id}'...");
137+
if let Err(e) = self.storage.delete(&id, data).await {
138+
rocket::warn!("Error while deleting session '{id}': {e}");
138139
} else {
139-
rocket::debug!("Deleted session '{deleted_id}' successfully");
140+
rocket::debug!("Deleted session '{id}' successfully");
140141
}
141142
}
142143

143144
// Handle updated session
144-
if let Some((id, pending_data, ttl)) = updated {
145+
if let Some((id, data, ttl)) = updated {
145146
rocket::debug!("Found updated session. Saving session '{id}'...");
146-
if let Err(e) = self.storage.save(&id, pending_data, ttl).await {
147+
if let Err(e) = self.storage.save(&id, data, ttl).await {
147148
rocket::error!("Error while saving session '{id}': {e}");
148149
} else {
149150
rocket::debug!("Saved session '{id}' successfully");

src/session_inner.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ use crate::SessionIdentifier;
77
pub(crate) struct SessionInner<T> {
88
/// The current, active session
99
current: Option<ActiveSession<T>>,
10-
/// The ID of the original session if deleted during the request
11-
deleted: Option<String>,
10+
/// The original session if deleted during the request
11+
deleted: Option<ActiveSession<T>>,
1212
}
1313
impl<T> Default for SessionInner<T> {
1414
fn default() -> Self {
1515
Self::new_empty()
1616
}
1717
}
1818

19-
/// Represents a current, active session
19+
/// Represents an active session
2020
#[derive(Debug)]
2121
struct ActiveSession<T> {
2222
/// Session ID (20-character alphanumeric string)
@@ -156,28 +156,28 @@ impl<T> SessionInner<T> {
156156
}
157157
}
158158

159-
/// Mark the current session ID as deleted, and clear all data. Can safely be called
159+
/// Mark the current session as deleted, and clear all data. Can safely be called
160160
/// multiple times in a request if needed - the original session will still be deleted.
161161
pub(crate) fn delete(&mut self) {
162162
if let Some(current) = self.current.take() {
163-
self.deleted.get_or_insert(current.id);
163+
self.deleted.get_or_insert(current);
164164
}
165165
}
166166

167167
pub(crate) fn get_deleted_id(&self) -> Option<&str> {
168-
self.deleted.as_deref()
168+
self.deleted.as_ref().map(|s| s.id.as_str())
169169
}
170170

171171
/// Get all data for storage if the session needs to be saved/updated. Returns a tuple of Options
172-
/// representing an updated session along with the id of a deleted session. This should only be
173-
/// called once at the end of the request, as it takes ownership of the session data.
174-
pub(crate) fn take_for_storage(&mut self) -> (Option<(String, T, u32)>, Option<String>) {
172+
/// representing an updated session along with a deleted session. This should only be
173+
/// called once at the end of the request, as it takes ownership of all data.
174+
pub(crate) fn take_for_storage(&mut self) -> (Option<(String, T, u32)>, Option<(String, T)>) {
175175
let updated_session = self
176176
.current
177177
.take()
178178
.filter(|c| should_save_session(&c.status))
179179
.map(|c| (c.id, c.data, c.ttl));
180-
(updated_session, self.deleted.take())
180+
(updated_session, self.deleted.take().map(|s| (s.id, s.data)))
181181
}
182182
}
183183

src/storage/cookie.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ where
172172
Ok(()) // no-op (cookie session should already be saved by `save_cookie`)
173173
}
174174

175-
async fn delete(&self, _id: &str, _cookie_jar: &CookieJar) -> SessionResult<()> {
175+
async fn delete(&self, _id: &str, _data: T) -> SessionResult<()> {
176176
Ok(()) // no-op (cookie session should already be deleted by `save_cookie`)
177177
}
178178
}

src/storage/interface.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ where
2525
async fn save(&self, id: &str, data: T, ttl: u32) -> SessionResult<()>;
2626

2727
/// Delete a session in storage. This will be performed at the end of the request lifecycle.
28-
async fn delete(&self, id: &str, cookie_jar: &CookieJar) -> SessionResult<()>;
28+
async fn delete(&self, id: &str, data: T) -> SessionResult<()>;
2929

3030
/// Optional callback when there's a pending change to the session data. A `data` value
3131
/// of `None` indicates a deleted session. This callback can be used by cookie-based

src/storage/memory.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ where
7373
Ok(())
7474
}
7575

76-
async fn delete(&self, id: &str, _cookie_jar: &CookieJar) -> SessionResult<()> {
76+
async fn delete(&self, id: &str, _data: T) -> SessionResult<()> {
7777
self.cache.remove(&id.to_owned()).await;
7878
Ok(())
7979
}
@@ -211,14 +211,9 @@ where
211211
self.base_storage.save(id, data, ttl).await
212212
}
213213

214-
async fn delete(&self, id: &str, cookie_jar: &CookieJar) -> SessionResult<()> {
215-
// Get the data first so we can update the index
216-
if let Ok((data, _)) = self.base_storage.load(id, None, cookie_jar).await {
217-
self.remove_from_identifier_index(id, &data);
218-
}
219-
220-
// Delete using base storage
221-
self.base_storage.delete(id, cookie_jar).await
214+
async fn delete(&self, id: &str, data: T) -> SessionResult<()> {
215+
self.remove_from_identifier_index(id, &data);
216+
self.base_storage.delete(id, data).await
222217
}
223218

224219
async fn setup(&self) -> SessionResult<()> {

src/storage/redis/storage.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ where
3333
Ok(())
3434
}
3535

36-
async fn delete(&self, id: &str, _cookie_jar: &CookieJar) -> SessionResult<()> {
36+
async fn delete(&self, id: &str, _data: T) -> SessionResult<()> {
3737
let _: () = self.pool.del(self.session_key(id)).await?;
3838
Ok(())
3939
}

src/storage/redis/storage_indexed.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,7 @@ where
9999
self.base_storage.save_session(id, value, ttl).await
100100
}
101101

102-
async fn delete(&self, id: &str, _cookie_jar: &CookieJar) -> SessionResult<()> {
103-
let (value, _) = self.base_storage.fetch_session(id, None).await?;
104-
let data = T::from_value(value)?;
105-
102+
async fn delete(&self, id: &str, data: T) -> SessionResult<()> {
106103
let pipeline = self.base_storage.pool.next().pipeline();
107104
let _: () = pipeline.del(self.base_storage.session_key(id)).await?;
108105
if let Some(identifier) = data.identifier() {

src/storage/sqlx/postgres.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ where
170170
Ok(())
171171
}
172172

173-
async fn delete(&self, id: &str, _cookie_jar: &CookieJar) -> SessionResult<()> {
173+
async fn delete(&self, id: &str, _data: T) -> SessionResult<()> {
174174
let sql = format!("DELETE FROM {} WHERE {ID_COLUMN} = $1", &self.table_name);
175175
sqlx::query(&sql).bind(id).execute(&self.pool).await?;
176176

tests/storages_indexed.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ mod common;
22

33
use std::{collections::HashMap, future::Future, pin::Pin};
44

5-
use rocket::{futures::FutureExt, local::asynchronous::Client};
5+
use rocket::futures::FutureExt;
66
use rocket_flex_session::{
77
storage::{
88
memory::MemoryStorageIndexed,
@@ -308,7 +308,6 @@ async fn invalidate_all_but_one_by_identifier(storage_case: &str) {
308308
#[test_case("redis"; "Redis Fred")]
309309
#[rocket::async_test]
310310
async fn delete_single_session(storage_case: &str) {
311-
let client = Client::tracked(rocket::build()).await.unwrap();
312311
let (storage, cleanup_task) = create_storage(storage_case).await;
313312
storage.setup().await.unwrap();
314313

@@ -336,7 +335,7 @@ async fn delete_single_session(storage_case: &str) {
336335
);
337336

338337
// Delete one session
339-
storage.delete("sid1", &client.cookies()).await.unwrap();
338+
storage.delete("sid1", session1.clone()).await.unwrap();
340339

341340
// Verify only one session remains
342341
let remaining_sessions = storage

0 commit comments

Comments
 (0)