tauri_plugin_http/
lib.rs

1// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
2// SPDX-License-Identifier: Apache-2.0
3// SPDX-License-Identifier: MIT
4
5//! Access the HTTP client written in Rust.
6
7pub 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}