salvo_flash/
cookie_store.rs1use salvo_core::http::cookie::time::Duration;
2use salvo_core::http::cookie::{Cookie, SameSite};
3use salvo_core::{Depot, Request, Response};
4
5use super::{Flash, FlashHandler, FlashStore};
6
7#[derive(Debug)]
9#[non_exhaustive]
10pub struct CookieStore {
11 pub max_age: Duration,
13 pub same_site: SameSite,
15 pub http_only: bool,
17 pub path: String,
19 pub name: String,
21}
22impl Default for CookieStore {
23 fn default() -> Self {
24 Self::new()
25 }
26}
27
28impl CookieStore {
29 pub fn new() -> Self {
31 Self {
32 max_age: Duration::seconds(60),
33 same_site: SameSite::Lax,
34 http_only: true,
35 path: "/".into(),
36 name: "salvo.flash".into(),
37 }
38 }
39
40 pub fn name(mut self, name: impl Into<String>) -> Self {
42 self.name = name.into();
43 self
44 }
45
46 pub fn max_age(mut self, max_age: Duration) -> Self {
48 self.max_age = max_age;
49 self
50 }
51
52 pub fn same_site(mut self, same_site: SameSite) -> Self {
54 self.same_site = same_site;
55 self
56 }
57
58 pub fn http_only(mut self, http_only: bool) -> Self {
60 self.http_only = http_only;
61 self
62 }
63
64 pub fn path(mut self, path: impl Into<String>) -> Self {
66 self.path = path.into();
67 self
68 }
69
70 pub fn into_handler(self) -> FlashHandler<CookieStore> {
72 FlashHandler::new(self)
73 }
74}
75impl FlashStore for CookieStore {
76 async fn load_flash(&self, req: &mut Request, _depot: &mut Depot) -> Option<Flash> {
77 match req.cookie(&self.name) {
78 None => None,
79 Some(cookie) => match serde_json::from_str(cookie.value()) {
80 Ok(flash) => Some(flash),
81 Err(e) => {
82 tracing::error!(error = ?e, "deserialize flash cookie failed");
83 None
84 }
85 },
86 }
87 }
88 async fn save_flash(&self, _req: &mut Request, _depot: &mut Depot, res: &mut Response, flash: Flash) {
89 res.add_cookie(
90 Cookie::build((self.name.clone(), serde_json::to_string(&flash).unwrap_or_default()))
91 .max_age(self.max_age)
92 .path(self.path.clone())
93 .same_site(self.same_site)
94 .http_only(self.http_only)
95 .build(),
96 );
97 }
98 async fn clear_flash(&self, _depot: &mut Depot, res: &mut Response) {
99 res.add_cookie(
100 Cookie::build((self.name.clone(), ""))
101 .max_age(Duration::seconds(0))
102 .same_site(self.same_site)
103 .http_only(self.http_only)
104 .path(self.path.clone())
105 .build(),
106 );
107 }
108}