actix / actix-extras

@@ -1,18 +1,16 @@
Loading
1 -
//! User sessions.
1 +
//! Sessions for Actix Web.
2 2
//!
3 -
//! Actix provides a general solution for session management. Session
4 -
//! middlewares could provide different implementations which could
5 -
//! be accessed via general session api.
3 +
//! Provides a general solution for session management. Session middleware could provide different
4 +
//! implementations which could be accessed via general session API.
6 5
//!
7 -
//! By default, only cookie session backend is implemented. Other
8 -
//! backend implementations can be added.
6 +
//! This crate provides a general solution for session management and includes a cookie backend.
7 +
//! Other backend implementations can be built to use persistent or key-value stores, for example.
9 8
//!
10 -
//! In general, you insert a *session* middleware and initialize it
11 -
//! , such as a `CookieSessionBackend`. To access session data,
12 -
//! [*Session*](struct.Session.html) extractor must be used. Session
13 -
//! extractor allows us to get or set session data.
9 +
//! In general, some session middleware, such as a [`CookieSession`] is initialized and applied.
10 +
//! To access session data, the [`Session`] extractor must be used. This extractor allows reading
11 +
//! modifying session data.
14 12
//!
15 -
//! ```rust,no_run
13 +
//! ```no_run
16 14
//! use actix_web::{web, App, HttpServer, HttpResponse, Error};
17 15
//! use actix_session::{Session, CookieSession};
18 16
//!
@@ -20,7 +18,7 @@
Loading
20 18
//!     // access session data
21 19
//!     if let Some(count) = session.get::<i32>("counter")? {
22 20
//!         println!("SESSION value: {}", count);
23 -
//!         session.set("counter", count+1)?;
21 +
//!         session.set("counter", count + 1)?;
24 22
//!     } else {
25 23
//!         session.set("counter", 1)?;
26 24
//!     }
@@ -31,12 +29,11 @@
Loading
31 29
//! #[actix_rt::main]
32 30
//! async fn main() -> std::io::Result<()> {
33 31
//!     HttpServer::new(
34 -
//!         || App::new().wrap(
35 -
//!               CookieSession::signed(&[0; 32]) // <- create cookie based session middleware
36 -
//!                     .secure(false)
37 -
//!              )
38 -
//!             .service(web::resource("/").to(|| HttpResponse::Ok())))
39 -
//!         .bind("127.0.0.1:59880")?
32 +
//!         || App::new()
33 +
//!             // create cookie based session middleware
34 +
//!             .wrap(CookieSession::signed(&[0; 32]).secure(false))
35 +
//!             .default_service(web::to(|| HttpResponse::Ok())))
36 +
//!         .bind(("127.0.0.1", 8080))?
40 37
//!         .run()
41 38
//!         .await
42 39
//! }
@@ -44,17 +41,14 @@
Loading
44 41
45 42
#![deny(rust_2018_idioms)]
46 43
47 -
use std::cell::RefCell;
48 -
use std::collections::HashMap;
49 -
use std::rc::Rc;
44 +
use std::{cell::RefCell, collections::HashMap, rc::Rc};
50 45
51 46
use actix_web::dev::{
52 47
    Extensions, Payload, RequestHead, ServiceRequest, ServiceResponse,
53 48
};
54 49
use actix_web::{Error, FromRequest, HttpMessage, HttpRequest};
55 50
use futures_util::future::{ok, Ready};
56 -
use serde::de::DeserializeOwned;
57 -
use serde::Serialize;
51 +
use serde::{de::DeserializeOwned, Serialize};
58 52
59 53
#[cfg(feature = "cookie-session")]
60 54
mod cookie;
@@ -63,16 +57,14 @@
Loading
63 57
64 58
/// The high-level interface you use to modify session data.
65 59
///
66 -
/// Session object could be obtained with
67 -
/// [`UserSession::get_session`](trait.UserSession.html#tymethod.get_session)
68 -
/// method. The `UserSession` trait is implemented for `HttpRequest`, `ServiceRequest`, and
69 -
/// `RequestHead`.
60 +
/// Session object is obtained with [`UserSession::get_session`]. The [`UserSession`] trait is
61 +
/// implemented for `HttpRequest`, `ServiceRequest`, and `RequestHead`.
70 62
///
71 -
/// ```rust
63 +
/// ```
72 64
/// use actix_session::Session;
73 -
/// use actix_web::*;
65 +
/// use actix_web::Result;
74 66
///
75 -
/// fn index(session: Session) -> Result<&'static str> {
67 +
/// async fn index(session: Session) -> Result<&'static str> {
76 68
///     // access session data
77 69
///     if let Some(count) = session.get::<i32>("counter")? {
78 70
///         session.set("counter", count + 1)?;
@@ -82,11 +74,10 @@
Loading
82 74
///
83 75
///     Ok("Welcome!")
84 76
/// }
85 -
/// # fn main() {}
86 77
/// ```
87 78
pub struct Session(Rc<RefCell<SessionInner>>);
88 79
89 -
/// Helper trait that allows to get session
80 +
/// Extraction of a [`Session`] object.
90 81
pub trait UserSession {
91 82
    fn get_session(&self) -> Session;
92 83
}
@@ -188,12 +179,10 @@
Loading
188 179
    /// Values that match keys already existing on the session will be overwritten. Values should
189 180
    /// already be JSON serialized.
190 181
    ///
191 -
    /// # Example
192 -
    ///
182 +
    /// # Examples
193 183
    /// ```
194 184
    /// # use actix_session::Session;
195 185
    /// # use actix_web::test;
196 -
    /// #
197 186
    /// let mut req = test::TestRequest::default().to_srv_request();
198 187
    ///
199 188
    /// Session::set_session(

@@ -43,62 +43,70 @@
Loading
43 43
            secure: false,
44 44
            max_age: Some(Duration::days(7)),
45 45
            same_site: None,
46 -
            http_only: Some(true),
46 +
            http_only: true,
47 47
        }))
48 48
    }
49 49
50 -
    /// Set time to live in seconds for session value
50 +
    /// Set time to live in seconds for session value.
51 51
    pub fn ttl(mut self, ttl: u32) -> Self {
52 52
        Rc::get_mut(&mut self.0).unwrap().ttl = format!("{}", ttl);
53 53
        self
54 54
    }
55 55
56 -
    /// Set custom cookie name for session id
56 +
    /// Set custom cookie name for session ID.
57 57
    pub fn cookie_name(mut self, name: &str) -> Self {
58 58
        Rc::get_mut(&mut self.0).unwrap().name = name.to_owned();
59 59
        self
60 60
    }
61 61
62 -
    /// Set custom cookie path
62 +
    /// Set custom cookie path.
63 63
    pub fn cookie_path(mut self, path: &str) -> Self {
64 64
        Rc::get_mut(&mut self.0).unwrap().path = path.to_owned();
65 65
        self
66 66
    }
67 67
68 -
    /// Set custom cookie domain
68 +
    /// Set custom cookie domain.
69 69
    pub fn cookie_domain(mut self, domain: &str) -> Self {
70 70
        Rc::get_mut(&mut self.0).unwrap().domain = Some(domain.to_owned());
71 71
        self
72 72
    }
73 73
74 -
    /// Set custom cookie secure
74 +
    /// Set custom cookie secure.
75 +
    ///
75 76
    /// If the `secure` field is set, a cookie will only be transmitted when the
76 -
    /// connection is secure - i.e. `https`
77 +
    /// connection is secure - i.e. `https`.
78 +
    ///
79 +
    /// Default is false.
77 80
    pub fn cookie_secure(mut self, secure: bool) -> Self {
78 81
        Rc::get_mut(&mut self.0).unwrap().secure = secure;
79 82
        self
80 83
    }
81 84
82 -
    /// Set custom cookie max-age
83 -
    /// Use `None` for session-only cookies
85 +
    /// Set custom cookie max-age.
86 +
    ///
87 +
    /// Use `None` for session-only cookies.
84 88
    pub fn cookie_max_age(mut self, max_age: impl Into<Option<Duration>>) -> Self {
85 89
        Rc::get_mut(&mut self.0).unwrap().max_age = max_age.into();
86 90
        self
87 91
    }
88 92
89 -
    /// Set custom cookie SameSite
93 +
    /// Set custom cookie `SameSite` attribute.
94 +
    ///
95 +
    /// By default, the attribute is omitted.
90 96
    pub fn cookie_same_site(mut self, same_site: SameSite) -> Self {
91 97
        Rc::get_mut(&mut self.0).unwrap().same_site = Some(same_site);
92 98
        self
93 99
    }
94 100
95 -
    /// Set custom cookie HttpOnly policy
101 +
    /// Set custom cookie `HttpOnly` policy.
102 +
    ///
103 +
    /// Default is true.
96 104
    pub fn cookie_http_only(mut self, http_only: bool) -> Self {
97 -
        Rc::get_mut(&mut self.0).unwrap().http_only = Some(http_only);
105 +
        Rc::get_mut(&mut self.0).unwrap().http_only = http_only;
98 106
        self
99 107
    }
100 108
101 -
    /// Set a custom cache key generation strategy, expecting session key as input
109 +
    /// Set a custom cache key generation strategy, expecting session key as input.
102 110
    pub fn cache_keygen(mut self, keygen: Box<dyn Fn(&str) -> String>) -> Self {
103 111
        Rc::get_mut(&mut self.0).unwrap().cache_keygen = keygen;
104 112
        self
@@ -214,7 +222,7 @@
Loading
214 222
    secure: bool,
215 223
    max_age: Option<Duration>,
216 224
    same_site: Option<SameSite>,
217 -
    http_only: Option<bool>,
225 +
    http_only: bool,
218 226
}
219 227
220 228
impl Inner {
@@ -293,7 +301,7 @@
Loading
293 301
            let mut cookie = Cookie::new(self.name.clone(), value.clone());
294 302
            cookie.set_path(self.path.clone());
295 303
            cookie.set_secure(self.secure);
296 -
            cookie.set_http_only(self.http_only.unwrap_or(true));
304 +
            cookie.set_http_only(self.http_only);
297 305
298 306
            if let Some(ref domain) = self.domain {
299 307
                cookie.set_domain(domain.clone());

@@ -1,19 +1,4 @@
Loading
1 -
//! Cookie session.
2 -
//!
3 -
//! [**CookieSession**](struct.CookieSession.html)
4 -
//! uses cookies as session storage. `CookieSession` creates sessions
5 -
//! which are limited to storing fewer than 4000 bytes of data, as the payload
6 -
//! must fit into a single cookie. An internal server error is generated if a
7 -
//! session contains more than 4000 bytes.
8 -
//!
9 -
//! A cookie may have a security policy of *signed* or *private*. Each has
10 -
//! a respective `CookieSession` constructor.
11 -
//!
12 -
//! A *signed* cookie may be viewed but not modified by the client. A *private*
13 -
//! cookie may neither be viewed nor modified by the client.
14 -
//!
15 -
//! The constructors take a key as an argument. This is the private key
16 -
//! for cookie session - when this value is changed, all session data is lost.
1 +
//! Cookie based sessions. See docs for [`CookieSession`].
17 2
18 3
use std::collections::HashMap;
19 4
use std::rc::Rc;
@@ -180,7 +165,7 @@
Loading
180 165
/// than 4000 bytes.
181 166
///
182 167
/// A cookie may have a security policy of *signed* or *private*. Each has a
183 -
/// respective `CookieSessionBackend` constructor.
168 +
/// respective `CookieSession` constructor.
184 169
///
185 170
/// A *signed* cookie is stored on the client as plaintext alongside
186 171
/// a signature such that the cookie may be viewed but not modified by the
@@ -198,9 +183,8 @@
Loading
198 183
/// By default all cookies are percent encoded, but certain symbols may
199 184
/// cause troubles when reading cookie, if they are not properly percent encoded.
200 185
///
201 -
/// # Example
202 -
///
203 -
/// ```rust
186 +
/// # Examples
187 +
/// ```
204 188
/// use actix_session::CookieSession;
205 189
/// use actix_web::{web, App, HttpResponse, HttpServer};
206 190
///
@@ -215,7 +199,7 @@
Loading
215 199
pub struct CookieSession(Rc<CookieSessionInner>);
216 200
217 201
impl CookieSession {
218 -
    /// Construct new *signed* `CookieSessionBackend` instance.
202 +
    /// Construct new *signed* `CookieSession` instance.
219 203
    ///
220 204
    /// Panics if key length is less than 32 bytes.
221 205
    pub fn signed(key: &[u8]) -> CookieSession {
@@ -225,7 +209,7 @@
Loading
225 209
        )))
226 210
    }
227 211
228 -
    /// Construct new *private* `CookieSessionBackend` instance.
212 +
    /// Construct new *private* `CookieSession` instance.
229 213
    ///
230 214
    /// Panics if key length is less than 32 bytes.
231 215
    pub fn private(key: &[u8]) -> CookieSession {
Files Coverage
actix-cors 90.26%
actix-redis 85.01%
actix-session/src 89.07%
actix-web-httpauth/src 61.01%
actix-identity/src/lib.rs 95.96%
actix-protobuf/src/lib.rs 48.62%
Project Totals (29 files) 82.08%
1
comment: false
2

3
ignore: # ignore codecoverage on following paths
4
  - "**/examples"
5
  - ".github"
6
  - "**/*.md"
7
  - "**/*.toml"
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading