use session crate

session-crate
Ondřej Hruška 4 years ago
parent fdbc7947f6
commit 21b83758c8
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 15
      Cargo.lock
  2. 2
      Cargo.toml
  3. 11
      src/main.rs
  4. 77
      src/session.rs

15
Cargo.lock generated

@ -829,6 +829,7 @@ dependencies = [
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket_session 0.1.0 (git+https://git.ondrovo.com/packages/rocket_session.git)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_yaml 0.8.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -878,6 +879,19 @@ dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rocket_session"
version = "0.1.0"
source = "git+https://git.ondrovo.com/packages/rocket_session.git#2aaa877cb5121fcd19ac5e6f4817af9c8878d64b"
dependencies = [
"json_dotpath 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-demangle"
version = "0.1.16"
@ -1372,6 +1386,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rocket_codegen 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "79aa1366f9b2eccddc05971e17c5de7bb75a5431eb12c2b5c66545fd348647f4"
"checksum rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e0fa5c1392135adc0f96a02ba150ac4c765e27c58dbfd32aa40678e948f6e56f"
"checksum rocket_http 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1391457ee4e80b40d4b57fa5765c0f2836b20d73bcbee4e3f35d93cf3b80817"
"checksum rocket_session 0.1.0 (git+https://git.ondrovo.com/packages/rocket_session.git)" = "<none>"
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum safemem 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"

@ -16,6 +16,8 @@ json_dotpath = "0.1.2"
titlecase = "0.10.0"
rand = "0.7.2"
rocket_session = { git = "https://git.ondrovo.com/packages/rocket_session.git" }
# special data structure that preserves order
indexmap = { version="1.3.0", features=["serde-1"] }

@ -12,9 +12,11 @@ use serde_json::Value;
use rocket_contrib::serve::StaticFiles;
use rocket_contrib::templates::Template;
mod session;
//mod session;
mod store;
use rocket_session::Session;
use crate::store::form::{
collect_card_form, render_card_fields, render_empty_fields, MapFromForm, RenderedCard,
RenderedField,
@ -22,11 +24,12 @@ use crate::store::form::{
use crate::store::Store;
use parking_lot::RwLock;
use crate::session::{Session, SessionID, SessionStore};
//use crate::session::Session;
use rocket::request::Form;
use rocket::response::Redirect;
use rocket::{Request, State};
use rocket::State;
use std::env;
use std::time::Duration;
#[derive(Serialize, Debug)]
pub struct ListContext<'a> {
@ -187,7 +190,7 @@ fn main() {
rocket::ignite()
.attach(Template::fairing())
.attach(Session::fairing())
.attach(Session::fairing(Duration::from_secs(3600)))
.manage(RwLock::new(store))
.mount("/", StaticFiles::from(cwd.join("templates/static/")))
.mount(

@ -1,19 +1,20 @@
use json_dotpath::DotPaths;
use parking_lot::{Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
use parking_lot::RwLock;
use rand::Rng;
use rocket::fairing::{self, Fairing, Info};
use rocket::request::FromRequest;
use rocket::response::ResponseBuilder;
use rocket::{
http::{Cookie, Cookies, Status},
Data, Outcome, Request, Response, Rocket, State,
http::{Cookie, Status},
Outcome, Request, Response, Rocket, State,
};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use serde::Serialize;
use serde_json::{Map, Value};
use std::borrow::Cow;
use std::collections::HashMap;
use std::ops::{Deref, DerefMut};
use std::time::{Instant, Duration};
use std::ops::Add;
const SESSION_ID: &'static str = "SESSID";
@ -22,12 +23,13 @@ type SessionsMap = HashMap<String, SessionInstance>;
#[derive(Debug)]
struct SessionInstance {
data: serde_json::Map<String, Value>,
// TODO expiration
expires: Instant,
}
#[derive(Default, Debug)]
pub struct SessionStore {
inner: RwLock<SessionsMap>,
lifespan: Duration,
}
#[derive(PartialEq, Hash, Clone, Debug)]
@ -88,15 +90,34 @@ impl<'a> Session<'a> {
SessionFairing
}
pub fn get<T: DeserializeOwned>(&self, path: &str) -> Option<T> {
let rg = self.store.inner.read();
if let Some(ses) = rg.get(&self.id.0) {
ses.data.dot_get(path)
fn tap<T>(&self, func : impl FnOnce(&mut serde_json::Map<String, Value>) -> T) -> T {
let mut wg = self.store.inner.write();
if let Some(instance) = wg.get_mut(&self.id.0) {
instance.expires = Instant::now().add(self.store.lifespan);
func(&mut instance.data)
} else {
None
let mut data = Map::new();
let rv = func(&mut data);
wg.insert(self.id.0.clone(), SessionInstance {
data: data,
expires: Instant::now().add(self.store.lifespan),
});
rv
}
}
pub fn renew(&self) {
self.tap(|_| ())
}
pub fn reset(&self) {
self.tap(|data| data.clear())
}
pub fn get<T: DeserializeOwned>(&self, path: &str) -> Option<T> {
self.tap(|data| data.dot_get(path))
}
pub fn get_or<T: DeserializeOwned>(&self, path: &str, def: T) -> T {
self.get(path).unwrap_or(def)
}
@ -110,39 +131,19 @@ impl<'a> Session<'a> {
}
pub fn take<T: DeserializeOwned>(&self, path: &str) -> Option<T> {
let mut wg = self.store.inner.write();
if let Some(ses) = wg.get_mut(&self.id.0) {
ses.data.dot_take(path)
} else {
None
}
self.tap(|data| data.dot_take(path))
}
pub fn replace<O: DeserializeOwned, N: Serialize>(&self, path: &str, new: N) -> Option<O> {
let mut wg = self.store.inner.write();
if let Some(ses) = wg.get_mut(&self.id.0) {
ses.data.dot_replace(path, new)
} else {
None
}
self.tap(|data| data.dot_replace(path, new))
}
pub fn set<T: Serialize>(&self, path: &str, value: T) {
let mut wg = self.store.inner.write();
if let Some(ses) = wg.get_mut(&self.id.0) {
ses.data.dot_set(path, value);
} else {
let mut map = Map::new();
map.dot_set(path, value);
wg.insert(self.id.0.clone(), SessionInstance { data: map });
}
self.tap(|data| data.dot_set(path, value));
}
pub fn remove(&self, path: &str) {
let mut wg = self.store.inner.write();
if let Some(ses) = wg.get_mut(&self.id.0) {
ses.data.dot_remove(path);
}
pub fn remove(&self, path: &str) -> bool {
self.tap(|data| data.dot_remove(path))
}
}

Loading…
Cancel
Save