orinium_browser/platform/network/
cookie_store.rs

1//! Cookie storage and management for HTTP requests.
2
3use std::collections::HashMap;
4use std::sync::{Arc, RwLock};
5use url::Url;
6
7#[allow(dead_code)]
8#[derive(Debug, Clone)]
9pub struct Cookie {
10    pub name: String,
11    pub value: String,
12    pub domain: String,
13    pub path: String,
14    pub secure: bool,
15}
16
17#[derive(Debug, Clone)]
18pub struct CookieStore {
19    store: Arc<RwLock<HashMap<String, Vec<Cookie>>>>, // domain -> cookies
20}
21
22impl Default for CookieStore {
23    fn default() -> Self {
24        Self::new()
25    }
26}
27
28impl CookieStore {
29    pub fn new() -> Self {
30        Self {
31            store: Arc::new(RwLock::new(HashMap::new())),
32        }
33    }
34
35    pub fn set_cookies(&self, url: &Url, cookie_headers: &[String]) {
36        let mut store = self.store.write().expect("RwLock poisoned");
37        let domain = url.host_str().unwrap_or_default().to_string();
38        let entry = store.entry(domain.clone()).or_default();
39
40        for hdr in cookie_headers {
41            if let Some((name, value)) = hdr.split_once('=') {
42                entry.push(Cookie {
43                    name: name.trim().to_string(),
44                    value: value.split(';').next().unwrap_or("").trim().to_string(),
45                    domain: domain.clone(),
46                    path: "/".to_string(),
47                    secure: url.scheme() == "https",
48                });
49            }
50        }
51    }
52
53    pub fn get_cookie_header(&self, url: &Url) -> Option<String> {
54        let store = self.store.read().ok()?;
55        let domain = url.host_str().unwrap_or_default();
56
57        store.get(domain).and_then(|cookies| {
58            let s = cookies
59                .iter()
60                .map(|c| format!("{}={}", c.name, c.value))
61                .collect::<Vec<_>>()
62                .join("; ");
63
64            if s.is_empty() { None } else { Some(s) }
65        })
66    }
67}