move code from tap to session's from_request, add tap_mut and make tap read-only
This commit is contained in:
parent
4a2287ee46
commit
af30c552ac
91
src/lib.rs
91
src/lib.rs
@ -55,22 +55,13 @@ impl<D> SessionStore<D>
|
||||
#[derive(PartialEq, Hash, Clone, Debug)]
|
||||
struct SessionID(String);
|
||||
|
||||
impl<'a, 'r> FromRequest<'a, 'r> for &'a SessionID {
|
||||
type Error = ();
|
||||
impl SessionID {
|
||||
fn as_str(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
|
||||
fn from_request(request: &'a Request<'r>) -> Outcome<Self, (Status, Self::Error), ()> {
|
||||
Outcome::Success(request.local_cache(|| {
|
||||
if let Some(cookie) = request.cookies().get(SESSION_COOKIE) {
|
||||
SessionID(cookie.value().to_string()) // FIXME avoid cloning (cow?)
|
||||
} else {
|
||||
SessionID(
|
||||
rand::thread_rng()
|
||||
.sample_iter(&rand::distributions::Alphanumeric)
|
||||
.take(16)
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}))
|
||||
fn to_string(&self) -> String {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,9 +84,11 @@ impl<'a, 'r, D> FromRequest<'a, 'r> for Session<'a, D>
|
||||
type Error = ();
|
||||
|
||||
fn from_request(request: &'a Request<'r>) -> Outcome<Self, (Status, Self::Error), ()> {
|
||||
let store : State<SessionStore<D>> = request.guard().unwrap();
|
||||
Outcome::Success(Session {
|
||||
id: request.local_cache(|| {
|
||||
if let Some(cookie) = request.cookies().get(SESSION_COOKIE) {
|
||||
// Resolve session ID
|
||||
let id = if let Some(cookie) = request.cookies().get(SESSION_COOKIE) {
|
||||
SessionID(cookie.value().to_string())
|
||||
} else {
|
||||
SessionID(
|
||||
@ -104,9 +97,34 @@ impl<'a, 'r, D> FromRequest<'a, 'r> for Session<'a, D>
|
||||
.take(SESSION_ID_LEN)
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let new_expiration = Instant::now().add(store.lifespan);
|
||||
let mut wg = store.inner.write();
|
||||
match wg.get_mut(id.as_str()) {
|
||||
Some(ses) => {
|
||||
// Check expiration
|
||||
if ses.expires <= Instant::now() {
|
||||
ses.data = D::default();
|
||||
}
|
||||
// Update expiry timestamp
|
||||
ses.expires = new_expiration;
|
||||
},
|
||||
None => {
|
||||
// New session
|
||||
wg.insert(
|
||||
id.to_string(),
|
||||
SessionInstance {
|
||||
data: D::default(),
|
||||
expires: new_expiration,
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
id
|
||||
}),
|
||||
store: request.guard().unwrap(),
|
||||
store,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -130,42 +148,21 @@ impl<'a, D> Session<'a, D>
|
||||
|
||||
/// Set the session object to its default state
|
||||
pub fn reset(&self) {
|
||||
self.tap(|m| {
|
||||
self.tap_mut(|m| {
|
||||
*m = D::default();
|
||||
})
|
||||
}
|
||||
|
||||
/// Renew the session without changing any data
|
||||
pub fn renew(&self) {
|
||||
self.tap(|_| ())
|
||||
pub fn tap<T>(&self, func: impl FnOnce(&D) -> T) -> T {
|
||||
let rg = self.store.inner.read();
|
||||
let instance = rg.get(self.id.as_str()).unwrap();
|
||||
func(&instance.data)
|
||||
}
|
||||
|
||||
/// Run a closure with a mutable reference to the session object.
|
||||
/// The closure's return value is send to the caller.
|
||||
pub fn tap<T>(&self, func: impl FnOnce(&mut D) -> T) -> T {
|
||||
pub fn tap_mut<T>(&self, func: impl FnOnce(&mut D) -> T) -> T {
|
||||
let mut wg = self.store.inner.write();
|
||||
if let Some(instance) = wg.get_mut(&self.id.0) {
|
||||
// wipe session data if expired
|
||||
if instance.expires <= Instant::now() {
|
||||
instance.data = D::default();
|
||||
}
|
||||
// update expiry timestamp
|
||||
instance.expires = Instant::now().add(self.store.lifespan);
|
||||
|
||||
func(&mut instance.data)
|
||||
} else {
|
||||
// no object in the store yet, start fresh
|
||||
let mut data = D::default();
|
||||
let result = func(&mut data);
|
||||
wg.insert(
|
||||
self.id.0.clone(),
|
||||
SessionInstance {
|
||||
data,
|
||||
expires: Instant::now().add(self.store.lifespan),
|
||||
},
|
||||
);
|
||||
result
|
||||
}
|
||||
let instance = wg.get_mut(self.id.as_str()).unwrap();
|
||||
func(&mut instance.data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user