rust_web_server/cookie/
mod.rs1#[cfg(test)]
2mod tests;
3
4#[cfg(feature = "crypto")]
5mod crypto_ext;
6#[cfg(feature = "crypto")]
7pub use crypto_ext::{decrypt_cookie, encrypted_cookie, signed_cookie, verify_signed_cookie};
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct Cookie {
12 pub name: String,
13 pub value: String,
14}
15
16pub struct CookieJar {
26 pub cookies: Vec<Cookie>,
27}
28
29impl CookieJar {
30 pub fn parse(header_value: &str) -> CookieJar {
32 let cookies = header_value
33 .split(';')
34 .filter_map(|pair| {
35 let pair = pair.trim();
36 let mut parts = pair.splitn(2, '=');
37 let name = parts.next()?.trim().to_string();
38 let value = parts.next().unwrap_or("").trim().to_string();
39 if name.is_empty() { None } else { Some(Cookie { name, value }) }
40 })
41 .collect();
42 CookieJar { cookies }
43 }
44
45 pub fn get(&self, name: &str) -> Option<&Cookie> {
47 self.cookies.iter().find(|c| c.name == name)
48 }
49}
50
51pub struct SetCookie {
68 pub name: String,
69 pub value: String,
70 pub path: Option<String>,
71 pub domain: Option<String>,
72 pub max_age: Option<i64>,
73 pub secure: bool,
74 pub http_only: bool,
75 pub same_site: Option<String>,
76}
77
78impl SetCookie {
79 pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
80 SetCookie {
81 name: name.into(),
82 value: value.into(),
83 path: None,
84 domain: None,
85 max_age: None,
86 secure: false,
87 http_only: false,
88 same_site: None,
89 }
90 }
91
92 pub fn path(mut self, path: impl Into<String>) -> Self {
93 self.path = Some(path.into());
94 self
95 }
96
97 pub fn domain(mut self, domain: impl Into<String>) -> Self {
98 self.domain = Some(domain.into());
99 self
100 }
101
102 pub fn max_age(mut self, seconds: i64) -> Self {
103 self.max_age = Some(seconds);
104 self
105 }
106
107 pub fn secure(mut self) -> Self {
108 self.secure = true;
109 self
110 }
111
112 pub fn http_only(mut self) -> Self {
113 self.http_only = true;
114 self
115 }
116
117 pub fn same_site(mut self, policy: impl Into<String>) -> Self {
118 self.same_site = Some(policy.into());
119 self
120 }
121
122 pub fn build(&self) -> String {
124 let mut s = format!("{}={}", self.name, self.value);
125 if let Some(ref p) = self.path { s.push_str(&format!("; Path={}", p)); }
126 if let Some(ref d) = self.domain { s.push_str(&format!("; Domain={}", d)); }
127 if let Some(age) = self.max_age { s.push_str(&format!("; Max-Age={}", age)); }
128 if self.secure { s.push_str("; Secure"); }
129 if self.http_only { s.push_str("; HttpOnly"); }
130 if let Some(ref ss) = self.same_site { s.push_str(&format!("; SameSite={}", ss)); }
131 s
132 }
133}