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 #[must_use]
31 pub fn new() -> Self {
32 Self {
33 max_age: Duration::seconds(60),
34 same_site: SameSite::Lax,
35 http_only: true,
36 path: "/".into(),
37 name: "salvo.flash".into(),
38 }
39 }
40
41 #[must_use]
43 pub fn name(mut self, name: impl Into<String>) -> Self {
44 self.name = name.into();
45 self
46 }
47
48 #[must_use]
50 pub fn max_age(mut self, max_age: Duration) -> Self {
51 self.max_age = max_age;
52 self
53 }
54
55 #[must_use]
57 pub fn same_site(mut self, same_site: SameSite) -> Self {
58 self.same_site = same_site;
59 self
60 }
61
62 #[must_use]
64 pub fn http_only(mut self, http_only: bool) -> Self {
65 self.http_only = http_only;
66 self
67 }
68
69 #[must_use]
71 pub fn path(mut self, path: impl Into<String>) -> Self {
72 self.path = path.into();
73 self
74 }
75
76 #[must_use]
78 pub fn into_handler(self) -> FlashHandler<Self> {
79 FlashHandler::new(self)
80 }
81}
82impl FlashStore for CookieStore {
83 async fn load_flash(&self, req: &mut Request, _depot: &mut Depot) -> Option<Flash> {
84 match req.cookie(&self.name) {
85 None => None,
86 Some(cookie) => match serde_json::from_str(cookie.value()) {
87 Ok(flash) => Some(flash),
88 Err(e) => {
89 tracing::error!(error = ?e, "deserialize flash cookie failed");
90 None
91 }
92 },
93 }
94 }
95 async fn save_flash(
96 &self,
97 _req: &mut Request,
98 _depot: &mut Depot,
99 res: &mut Response,
100 flash: Flash,
101 ) {
102 res.add_cookie(
103 Cookie::build((
104 self.name.clone(),
105 serde_json::to_string(&flash).unwrap_or_default(),
106 ))
107 .max_age(self.max_age)
108 .path(self.path.clone())
109 .same_site(self.same_site)
110 .http_only(self.http_only)
111 .build(),
112 );
113 }
114 async fn clear_flash(&self, _depot: &mut Depot, res: &mut Response) {
115 res.add_cookie(
116 Cookie::build((self.name.clone(), ""))
117 .max_age(Duration::seconds(0))
118 .same_site(self.same_site)
119 .http_only(self.http_only)
120 .path(self.path.clone())
121 .build(),
122 );
123 }
124}