windows_webview/
cookie.rs1use super::*;
2
3#[derive(Clone, Copy, Debug, PartialEq, Eq)]
6pub enum SameSite {
7 None,
10 Lax,
12 Strict,
14}
15
16impl SameSite {
17 fn from_raw(value: COREWEBVIEW2_COOKIE_SAME_SITE_KIND) -> Self {
18 match value {
19 0 => Self::None,
20 2 => Self::Strict,
21 _ => Self::Lax,
22 }
23 }
24
25 fn to_raw(self) -> COREWEBVIEW2_COOKIE_SAME_SITE_KIND {
26 match self {
27 Self::None => 0,
28 Self::Lax => 1,
29 Self::Strict => 2,
30 }
31 }
32}
33
34#[derive(Clone, Debug, PartialEq)]
37pub struct Cookie {
38 pub name: String,
39 pub value: String,
40 pub domain: String,
41 pub path: String,
42 pub is_secure: bool,
44 pub is_http_only: bool,
46 pub same_site: SameSite,
47 pub expires: Option<f64>,
50}
51
52impl Cookie {
53 pub fn new(name: &str, value: &str, domain: &str, path: &str) -> Self {
58 Self {
59 name: name.to_string(),
60 value: value.to_string(),
61 domain: domain.to_string(),
62 path: path.to_string(),
63 is_secure: false,
64 is_http_only: false,
65 same_site: SameSite::Lax,
66 expires: None,
67 }
68 }
69
70 fn from_com(cookie: &ICoreWebView2Cookie) -> Result<Self> {
71 unsafe {
72 let expires = if cookie.IsSession()?.as_bool() {
73 None
74 } else {
75 Some(cookie.Expires()?)
76 };
77 Ok(Self {
78 name: string::take(cookie.Name()?),
79 value: string::take(cookie.Value()?),
80 domain: string::take(cookie.Domain()?),
81 path: string::take(cookie.Path()?),
82 is_secure: cookie.IsSecure()?.as_bool(),
83 is_http_only: cookie.IsHttpOnly()?.as_bool(),
84 same_site: SameSite::from_raw(cookie.SameSite()?),
85 expires,
86 })
87 }
88 }
89}
90
91pub struct CookieManager(pub(crate) ICoreWebView2CookieManager);
94
95impl CookieManager {
96 pub fn get_cookies<F: FnOnce(Result<Vec<Cookie>>) + 'static>(
100 &self,
101 uri: &str,
102 handler: F,
103 ) -> Result<()> {
104 let uri = HSTRING::from(uri);
105 let handler = handler::GetCookiesCompleted::create(handler);
106 unsafe { self.0.GetCookies(&uri, &handler) }.ok()
107 }
108
109 pub fn add_or_update_cookie(&self, cookie: &Cookie) -> Result<()> {
112 let name = HSTRING::from(&cookie.name);
113 let value = HSTRING::from(&cookie.value);
114 let domain = HSTRING::from(&cookie.domain);
115 let path = HSTRING::from(&cookie.path);
116 unsafe {
117 let raw = self.0.CreateCookie(&name, &value, &domain, &path)?;
118 raw.SetIsSecure(cookie.is_secure).ok()?;
119 raw.SetIsHttpOnly(cookie.is_http_only).ok()?;
120 raw.SetSameSite(cookie.same_site.to_raw()).ok()?;
121 if let Some(expires) = cookie.expires {
122 raw.SetExpires(expires).ok()?;
123 }
124 self.0.AddOrUpdateCookie(&raw).ok()
125 }
126 }
127
128 pub fn delete_cookies(&self, name: &str, uri: &str) -> Result<()> {
130 let name = HSTRING::from(name);
131 let uri = HSTRING::from(uri);
132 unsafe { self.0.DeleteCookies(&name, &uri) }.ok()
133 }
134
135 pub fn delete_cookies_with_domain_and_path(
137 &self,
138 name: &str,
139 domain: &str,
140 path: &str,
141 ) -> Result<()> {
142 let name = HSTRING::from(name);
143 let domain = HSTRING::from(domain);
144 let path = HSTRING::from(path);
145 unsafe { self.0.DeleteCookiesWithDomainAndPath(&name, &domain, &path) }.ok()
146 }
147
148 pub fn delete_all_cookies(&self) -> Result<()> {
150 unsafe { self.0.DeleteAllCookies() }.ok()
151 }
152}
153
154pub(crate) fn collect(list: &ICoreWebView2CookieList) -> Result<Vec<Cookie>> {
155 let count = unsafe { list.Count()? };
156 let mut cookies = Vec::with_capacity(count as usize);
157 for index in 0..count {
158 let cookie = unsafe { list.GetValueAtIndex(index)? };
159 cookies.push(Cookie::from_com(&cookie)?);
160 }
161 Ok(cookies)
162}