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
2 changes: 1 addition & 1 deletion src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub struct RocketFlexSessionOptions {
/// The session cookie's `HttpOnly` attribute (default: `true`)
pub http_only: bool,
/// The session cookie's `Max-Age` attribute, in seconds. This also determines
/// the session storage TTL, unless you specify a different `ttl` setting. (default: 14 days)
/// the session storage TTL, unless you specify a different `ttl` setting. (default: 2 weeks)
pub max_age: u32,
/// The session cookie's `Path` attribute (default: `"/"`)
pub path: String,
Expand Down
8 changes: 5 additions & 3 deletions src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,11 @@ where
return;
};

// Generate new cookie
self.cookie_jar
.add_private(create_session_cookie(id, self.options));
// Generate new session cookie if needed
if inner.is_new() {
let session_cookie = create_session_cookie(id, self.options);
self.cookie_jar.add_private(session_cookie);
}

// Notify any cookie-based storage
let save_result = self.storage.save_cookie(
Expand Down
8 changes: 8 additions & 0 deletions src/session_inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ struct ActiveSession<T> {
pending_data: Option<T>,
/// Time-to-live in seconds
ttl: u32,
/// Whether this is a new session that hasn't been stored yet
new: bool,
}
impl<T: Clone> ActiveSession<T> {
/// Create a new active session with a generated ID, to be saved in storage
Expand All @@ -21,6 +23,7 @@ impl<T: Clone> ActiveSession<T> {
data: new_data.clone(),
pending_data: Some(new_data),
ttl,
new: true,
}
}
/// Active session that already exists in storage
Expand All @@ -30,6 +33,7 @@ impl<T: Clone> ActiveSession<T> {
data,
pending_data: None,
ttl,
new: false,
}
}
}
Expand Down Expand Up @@ -79,6 +83,10 @@ where
self.current.as_ref().map(|s| s.ttl)
}

pub(crate) fn is_new(&self) -> bool {
self.current.as_ref().map(|s| s.new).unwrap_or(false)
}

pub(crate) fn set_data(&mut self, new_data: T, default_ttl: u32) {
match &mut self.current {
Some(current) => current.pending_data = Some(new_data),
Expand Down
25 changes: 22 additions & 3 deletions tests/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,22 @@ fn test_set_and_get_session() {
.cookies()
.get_private("rocket")
.expect("should have session cookie");
let cookie_value = cookie.value().to_owned();

assert_eq!(set_response.status(), Status::Ok);
assert_eq!(cookie.value(), set_response.into_string().unwrap());
assert_eq!(cookie_value, set_response.into_string().unwrap());

// Get session
let get_response = client.get("/get_session").dispatch();
assert_eq!(get_response.status(), Status::Ok);
assert_eq!(get_response.into_string().unwrap(), "User: Test User (123)");

// Update session
let set_response = client.post("/set_session").dispatch();

// Verify cookie was not changed
assert_eq!(set_response.cookies().get_private("rocket"), None);
assert_eq!(set_response.status(), Status::Ok);
}

#[test]
Expand All @@ -152,17 +160,28 @@ fn test_hashmap_session() {
.dispatch();
assert_eq!(response.status(), Status::Ok);

// Verify cookie was set
// Verify session cookie was set
response
.cookies()
.get_private("hash_session")
.expect("should have session cookie");

// Get hash value
// Set another hash value, and verify session cookie was not changed
let response = client
.post("/set_hash_session/test_key_2/test_value")
.dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(response.cookies().get_private("hash_session"), None);

// Get hash values
let response = client.get("/get_hash_session/test_key").dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(response.into_string().unwrap(), "test_value");

let response = client.get("/get_hash_session/test_key_2").dispatch();
assert_eq!(response.status(), Status::Ok);
assert_eq!(response.into_string().unwrap(), "test_value");

// Get non-existent key
let response = client.get("/get_hash_session/invalid_key").dispatch();
assert_eq!(response.into_string().unwrap(), "No value");
Expand Down