|
4 | 4 |
|
5 | 5 | // taken from https://github.com/pfernie/reqwest_cookie_store/blob/2ec4afabcd55e24d3afe3f0626ee6dc97bed938d/src/lib.rs
|
6 | 6 |
|
7 |
| -use std::sync::{Mutex, MutexGuard, PoisonError}; |
| 7 | +use std::{ |
| 8 | + fs::File, |
| 9 | + io::BufWriter, |
| 10 | + path::PathBuf, |
| 11 | + sync::{Arc, Mutex, MutexGuard, PoisonError}, |
| 12 | +}; |
8 | 13 |
|
9 | 14 | use cookie_store::{CookieStore, RawCookie, RawCookieParseError};
|
10 | 15 | use reqwest::header::HeaderValue;
|
@@ -41,47 +46,61 @@ fn cookies(cookie_store: &CookieStore, url: &url::Url) -> Option<HeaderValue> {
|
41 | 46 |
|
42 | 47 | /// A [`cookie_store::CookieStore`] wrapped internally by a [`std::sync::Mutex`], suitable for use in
|
43 | 48 | /// async/concurrent contexts.
|
44 |
| -#[derive(Debug, Serialize, Deserialize)] |
45 |
| -pub struct CookieStoreMutex(Mutex<CookieStore>); |
46 |
| - |
47 |
| -impl Default for CookieStoreMutex { |
48 |
| - /// Create a new, empty [`CookieStoreMutex`] |
49 |
| - fn default() -> Self { |
50 |
| - CookieStoreMutex::new(CookieStore::default()) |
51 |
| - } |
| 49 | +#[derive(Debug, Clone, Serialize, Deserialize)] |
| 50 | +pub struct CookieStoreMutex { |
| 51 | + pub path: PathBuf, |
| 52 | + store: Arc<Mutex<CookieStore>>, |
52 | 53 | }
|
53 | 54 |
|
54 | 55 | impl CookieStoreMutex {
|
55 | 56 | /// Create a new [`CookieStoreMutex`] from an existing [`cookie_store::CookieStore`].
|
56 |
| - pub const fn new(cookie_store: CookieStore) -> CookieStoreMutex { |
57 |
| - CookieStoreMutex(Mutex::new(cookie_store)) |
| 57 | + pub fn new(path: PathBuf, cookie_store: CookieStore) -> CookieStoreMutex { |
| 58 | + CookieStoreMutex { |
| 59 | + path, |
| 60 | + store: Arc::new(Mutex::new(cookie_store)), |
| 61 | + } |
58 | 62 | }
|
59 | 63 |
|
60 | 64 | /// Lock and get a handle to the contained [`cookie_store::CookieStore`].
|
61 | 65 | pub fn lock(
|
62 | 66 | &self,
|
63 | 67 | ) -> Result<MutexGuard<'_, CookieStore>, PoisonError<MutexGuard<'_, CookieStore>>> {
|
64 |
| - self.0.lock() |
| 68 | + self.store.lock() |
65 | 69 | }
|
66 | 70 |
|
67 |
| - pub fn load<R: std::io::BufRead>(reader: R) -> cookie_store::Result<CookieStoreMutex> { |
68 |
| - cookie_store::serde::load(reader, |c| serde_json::from_str(c)).map(CookieStoreMutex::new) |
| 71 | + pub fn load<R: std::io::BufRead>( |
| 72 | + path: PathBuf, |
| 73 | + reader: R, |
| 74 | + ) -> cookie_store::Result<CookieStoreMutex> { |
| 75 | + cookie_store::serde::load(reader, |c| serde_json::from_str(c)) |
| 76 | + .map(|store| CookieStoreMutex::new(path, store)) |
69 | 77 | }
|
70 | 78 |
|
71 |
| - pub fn save<W: std::io::Write>(&self, writer: &mut W) -> cookie_store::Result<()> { |
| 79 | + pub fn save(&self) -> cookie_store::Result<()> { |
| 80 | + let file = File::create(&self.path)?; |
| 81 | + let mut writer = BufWriter::new(file); |
72 | 82 | let store = self.lock().expect("poisoned cookie jar mutex");
|
73 |
| - cookie_store::serde::save(&store, writer, serde_json::to_string) |
| 83 | + cookie_store::serde::save(&store, &mut writer, serde_json::to_string) |
74 | 84 | }
|
75 | 85 | }
|
76 | 86 |
|
77 | 87 | impl reqwest::cookie::CookieStore for CookieStoreMutex {
|
78 | 88 | fn set_cookies(&self, cookie_headers: &mut dyn Iterator<Item = &HeaderValue>, url: &url::Url) {
|
79 |
| - let mut store = self.0.lock().unwrap(); |
| 89 | + let mut store = self.store.lock().unwrap(); |
80 | 90 | set_cookies(&mut store, cookie_headers, url);
|
| 91 | + |
| 92 | + // try to persist cookies immediately asynchronously |
| 93 | + let cookies_jar = self.clone(); |
| 94 | + tauri::async_runtime::spawn(async move { |
| 95 | + if let Err(_e) = cookies_jar.save() { |
| 96 | + #[cfg(feature = "tracing")] |
| 97 | + tracing::error!("failed to save cookie jar: {_e}"); |
| 98 | + } |
| 99 | + }); |
81 | 100 | }
|
82 | 101 |
|
83 | 102 | fn cookies(&self, url: &url::Url) -> Option<HeaderValue> {
|
84 |
| - let store = self.0.lock().unwrap(); |
| 103 | + let store = self.store.lock().unwrap(); |
85 | 104 | cookies(&store, url)
|
86 | 105 | }
|
87 | 106 | }
|
0 commit comments