1pub use reqwest;
8use tauri::{
9 plugin::{Builder, TauriPlugin},
10 Manager, Runtime,
11};
12
13pub use error::{Error, Result};
14
15mod commands;
16mod error;
17#[cfg(feature = "cookies")]
18mod reqwest_cookie_store;
19mod scope;
20
21#[cfg(feature = "cookies")]
22const COOKIES_FILENAME: &str = ".cookies";
23
24pub(crate) struct Http {
25 #[cfg(feature = "cookies")]
26 cookies_jar: std::sync::Arc<crate::reqwest_cookie_store::CookieStoreMutex>,
27}
28
29pub fn init<R: Runtime>() -> TauriPlugin<R> {
30 Builder::<R>::new("http")
31 .setup(|app, _| {
32 #[cfg(feature = "cookies")]
33 let cookies_jar = {
34 use crate::reqwest_cookie_store::*;
35 use std::fs::File;
36 use std::io::BufReader;
37
38 let cache_dir = app.path().app_cache_dir()?;
39 std::fs::create_dir_all(&cache_dir)?;
40
41 let path = cache_dir.join(COOKIES_FILENAME);
42 let file = File::options()
43 .create(true)
44 .append(true)
45 .read(true)
46 .open(&path)?;
47
48 let reader = BufReader::new(file);
49 CookieStoreMutex::load(path.clone(), reader).unwrap_or_else(|_e| {
50 #[cfg(feature = "tracing")]
51 tracing::warn!(
52 "failed to load cookie store: {_e}, falling back to empty store"
53 );
54 CookieStoreMutex::new(path, Default::default())
55 })
56 };
57
58 let state = Http {
59 #[cfg(feature = "cookies")]
60 cookies_jar: std::sync::Arc::new(cookies_jar),
61 };
62
63 app.manage(state);
64
65 Ok(())
66 })
67 .on_event(|app, event| {
68 #[cfg(feature = "cookies")]
69 if let tauri::RunEvent::Exit = event {
70 let state = app.state::<Http>();
71
72 match state.cookies_jar.request_save() {
73 Ok(rx) => {
74 let _ = rx.recv();
75 }
76 Err(_e) => {
77 #[cfg(feature = "tracing")]
78 tracing::error!("failed to save cookie jar: {_e}");
79 }
80 }
81 }
82 })
83 .invoke_handler(tauri::generate_handler![
84 commands::fetch,
85 commands::fetch_cancel,
86 commands::fetch_send,
87 commands::fetch_read_body
88 ])
89 .build()
90}