From 58330f9ec1d631f95de7f790076c5417cbf35733 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Tue, 14 May 2024 01:39:36 +0300 Subject: [PATCH] feat(http): enable cookies and set origin header (#1192) --- .changes/http-cookies.md | 5 +++++ .changes/http-origin.md | 5 +++++ plugins/http/Cargo.toml | 3 ++- plugins/http/src/commands.rs | 24 ++++++++++++++---------- plugins/http/src/lib.rs | 32 ++++++++++++++------------------ 5 files changed, 40 insertions(+), 29 deletions(-) create mode 100644 .changes/http-cookies.md create mode 100644 .changes/http-origin.md diff --git a/.changes/http-cookies.md b/.changes/http-cookies.md new file mode 100644 index 00000000..57e493bf --- /dev/null +++ b/.changes/http-cookies.md @@ -0,0 +1,5 @@ +--- +"http": "patch" +--- + +Enable cookies store feature flag by default. diff --git a/.changes/http-origin.md b/.changes/http-origin.md new file mode 100644 index 00000000..8cc72898 --- /dev/null +++ b/.changes/http-origin.md @@ -0,0 +1,5 @@ +--- +"http": "patch" +--- + +Set the request origin to the current webview url. diff --git a/plugins/http/Cargo.toml b/plugins/http/Cargo.toml index 81fc8f63..e8a17380 100644 --- a/plugins/http/Cargo.toml +++ b/plugins/http/Cargo.toml @@ -39,7 +39,8 @@ default = [ "rustls-tls", "http2", "charset", - "macos-system-configuration" + "macos-system-configuration", + "cookies" ] multipart = [ "reqwest/multipart" ] json = [ "reqwest/json" ] diff --git a/plugins/http/src/commands.rs b/plugins/http/src/commands.rs index 4f93461c..e866da3c 100644 --- a/plugins/http/src/commands.rs +++ b/plugins/http/src/commands.rs @@ -4,19 +4,19 @@ use std::{collections::HashMap, future::Future, pin::Pin, sync::Arc, time::Duration}; -use http::{header, HeaderName, HeaderValue, Method, StatusCode}; +use http::{header, HeaderName, Method, StatusCode}; use reqwest::{redirect::Policy, NoProxy}; use serde::{Deserialize, Serialize}; use tauri::{ async_runtime::Mutex, command, ipc::{CommandScope, GlobalScope}, - Manager, ResourceId, Runtime, Webview, + Manager, ResourceId, Runtime, State, Webview, }; use crate::{ scope::{Entry, Scope}, - Error, Result, + Error, Http, Result, }; struct ReqwestResponse(reqwest::Response); @@ -138,6 +138,7 @@ fn attach_proxy( #[command] pub async fn fetch( webview: Webview, + state: State<'_, Http>, client_config: ClientConfig, command_scope: CommandScope, global_scope: GlobalScope, @@ -190,11 +191,15 @@ pub async fn fetch( builder = attach_proxy(proxy_config, builder)?; } + #[cfg(feature = "cookies")] + { + builder = builder.cookie_provider(state.cookies_jar.clone()); + } + let mut request = builder.build()?.request(method.clone(), url); for (name, value) in &headers { let name = HeaderName::from_bytes(name.as_bytes())?; - let value = HeaderValue::from_bytes(value.as_bytes())?; #[cfg(not(feature = "unsafe-headers"))] if matches!( name, @@ -228,22 +233,21 @@ pub async fn fetch( // POST and PUT requests should always have a 0 length content-length, // if there is no body. https://fetch.spec.whatwg.org/#http-network-or-cache-fetch if data.is_none() && matches!(method, Method::POST | Method::PUT) { - request = request.header(header::CONTENT_LENGTH, HeaderValue::from(0)); + request = request.header(header::CONTENT_LENGTH, 0); } if headers.contains_key(header::RANGE.as_str()) { // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch step 18 // If httpRequest’s header list contains `Range`, then append (`Accept-Encoding`, `identity`) - request = request.header( - header::ACCEPT_ENCODING, - HeaderValue::from_static("identity"), - ); + request = request.header(header::ACCEPT_ENCODING, "identity"); } if !headers.contains_key(header::USER_AGENT.as_str()) { - request = request.header(header::USER_AGENT, HeaderValue::from_static("tauri")); + request = request.header(header::USER_AGENT, "tauri-plugin-http"); } + request = request.header(header::ORIGIN, webview.url().as_str()); + if let Some(data) = data { request = request.body(data); } diff --git a/plugins/http/src/lib.rs b/plugins/http/src/lib.rs index 61274ded..cdffeb6e 100644 --- a/plugins/http/src/lib.rs +++ b/plugins/http/src/lib.rs @@ -9,7 +9,7 @@ pub use reqwest; use tauri::{ plugin::{Builder, TauriPlugin}, - AppHandle, Manager, Runtime, + Manager, Runtime, }; pub use error::{Error, Result}; @@ -18,32 +18,28 @@ mod commands; mod error; mod scope; -struct Http { - #[allow(dead_code)] - app: AppHandle, +pub(crate) struct Http { + #[cfg(feature = "cookies")] + cookies_jar: std::sync::Arc, } -/* trait HttpExt { - fn http(&self) -> &Http; -} - -impl> HttpExt for T { - fn http(&self) -> &Http { - self.state::>().inner() - } -} */ - pub fn init() -> TauriPlugin { Builder::::new("http") + .setup(|app, _| { + let state = Http { + #[cfg(feature = "cookies")] + cookies_jar: std::sync::Arc::new(reqwest::cookie::Jar::default()), + }; + + app.manage(state); + + Ok(()) + }) .invoke_handler(tauri::generate_handler![ commands::fetch, commands::fetch_cancel, commands::fetch_send, commands::fetch_read_body, ]) - .setup(|app, _api| { - app.manage(Http { app: app.clone() }); - Ok(()) - }) .build() }