Skip to content
Draft
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
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ description = "Generic session middleware for the warp HTTP framework"
repository = "https://github.com/ajpauwels/warp-sessions.git"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
async-session = "3.0.0"
async-session = { git = "https://github.com/http-rs/async-session", branch = "overhaul-session-and-session-store" }
async-trait = "0.1.63"
serde = { version = "1.0.152", features = ["derive"] }
warp = "0.3.3"
Expand Down
20 changes: 10 additions & 10 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,31 @@ use warp::reject::Reject;

/// Error type that converts to a warp::Rejection
#[derive(Debug)]
pub enum SessionError {
pub enum SessionError<E> {
/// Represents an error which occurred while loading a session from
/// the backing session store.
LoadError { source: async_session::Error },
LoadError { source: E },

/// Represents an error that occurred while saving a session to
/// the backing session store.
StoreError { source: async_session::Error },
StoreError { source: E },

/// Represents an error that occurred while destroying a session
/// record from the backing session store.
DestroyError { source: async_session::Error },
DestroyError { source: E },
}

impl Error for SessionError {
impl<E: Error + 'static> Error for SessionError<E> {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match *self {
SessionError::LoadError { ref source } => Some(source.as_ref()),
SessionError::StoreError { ref source } => Some(source.as_ref()),
SessionError::DestroyError { ref source } => Some(source.as_ref()),
SessionError::LoadError { ref source } => Some(source),
SessionError::StoreError { ref source } => Some(source),
SessionError::DestroyError { ref source } => Some(source),
}
}
}

impl Display for SessionError {
impl<E: Error> Display for SessionError<E> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match *self {
SessionError::LoadError { .. } => {
Expand All @@ -44,4 +44,4 @@ impl Display for SessionError {
}
}

impl Reject for SessionError {}
impl<E: Error + Send + Sync + 'static> Reject for SessionError<E> {}
9 changes: 7 additions & 2 deletions src/reply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ use warp::{Rejection, Reply};
/// to reply containing the ID of this particular session.
/// When the request::with_session filter runs, it will pick this cookie
/// up and restore the session from the store.
pub async fn with_session<T: Reply, S: SessionStore>(
pub async fn with_session<T, S>(
reply: T,
session_with_store: SessionWithStore<S>,
) -> Result<WithSession<T>, Rejection> {
) -> Result<WithSession<T>, Rejection>
where
T: Reply,
S: SessionStore + Send + Sync + 'static,
S::Error: Send + Sync + 'static,
{
WithSession::new(reply, session_with_store).await
}

Expand Down
8 changes: 6 additions & 2 deletions src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ use warp::{Filter, Rejection};
/// name 'sid' from the request and uses the passed in session store
/// to retrieve the session. It returns the session for use by the
/// downstream session handler.
pub fn with_session<T: SessionStore>(
pub fn with_session<T>(
session_store: T,
cookie_options: Option<CookieOptions>,
) -> impl Filter<Extract = (SessionWithStore<T>,), Error = Rejection> + Clone {
) -> impl Filter<Extract = (SessionWithStore<T>,), Error = Rejection> + Clone
where
T: SessionStore + Clone + Send + Sync + 'static,
T::Error: Send + Sync + 'static,
{
let cookie_options = match cookie_options {
Some(co) => co,
None => {
Expand Down
22 changes: 14 additions & 8 deletions src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,28 @@ pub struct ArcSessionStore<T: SessionStore>(pub Arc<T>);
#[async_trait]
impl<T> SessionStore for ArcSessionStore<T>
where
T: SessionStore,
T: SessionStore + Send + Sync + 'static,
T::Error: Send + Sync + 'static,
{
async fn load_session(&self, cookie_value: String) -> async_session::Result<Option<Session>> {
type Error = T::Error;
async fn load_session(&self, cookie_value: String) -> Result<Option<Session>, Self::Error> {
self.0.deref().load_session(cookie_value).await
}
async fn store_session(&self, session: Session) -> async_session::Result<Option<String>> {
async fn store_session(&self, session: Session) -> Result<Option<String>, Self::Error> {
self.0.deref().store_session(session).await
}
async fn destroy_session(&self, session: Session) -> async_session::Result {
async fn destroy_session(&self, session: Session) -> Result<(), Self::Error> {
self.0.deref().destroy_session(session).await
}
async fn clear_store(&self) -> async_session::Result {
async fn clear_store(&self) -> Result<(), Self::Error> {
self.0.deref().clear_store().await
}
}

/// SessionWithStore binds a session object with its backing store and some cookie options.
/// This is passed around by routes wanting to do things with a session.
#[derive(Clone)]
pub struct SessionWithStore<S: SessionStore> {
pub struct SessionWithStore<S> {
pub session: Session,
pub session_store: S,
pub cookie_options: CookieOptions,
Expand All @@ -52,10 +54,14 @@ where
/// header to it. This cookie contains the session ID. If the session was
/// destroyed, it handles destroying the session in the store and removing
/// the cookie.
pub async fn new<S: SessionStore>(
pub async fn new<S>(
reply: T,
session_with_store: SessionWithStore<S>,
) -> Result<WithSession<T>, Rejection> {
) -> Result<WithSession<T>, Rejection>
where
S: SessionStore + Send + Sync + 'static,
S::Error: Send + Sync + 'static,
{
let mut cookie_options = session_with_store.cookie_options;

if session_with_store.session.is_destroyed() {
Expand Down