mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-04-27 11:56:05 +02:00
feat(http): enable cookies and set origin header (#1192)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"http": "patch"
|
||||
---
|
||||
|
||||
Enable cookies store feature flag by default.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"http": "patch"
|
||||
---
|
||||
|
||||
Set the request origin to the current webview url.
|
||||
@@ -39,7 +39,8 @@ default = [
|
||||
"rustls-tls",
|
||||
"http2",
|
||||
"charset",
|
||||
"macos-system-configuration"
|
||||
"macos-system-configuration",
|
||||
"cookies"
|
||||
]
|
||||
multipart = [ "reqwest/multipart" ]
|
||||
json = [ "reqwest/json" ]
|
||||
|
||||
@@ -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<R: Runtime>(
|
||||
webview: Webview<R>,
|
||||
state: State<'_, Http>,
|
||||
client_config: ClientConfig,
|
||||
command_scope: CommandScope<Entry>,
|
||||
global_scope: GlobalScope<Entry>,
|
||||
@@ -190,11 +191,15 @@ pub async fn fetch<R: Runtime>(
|
||||
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<R: Runtime>(
|
||||
// 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);
|
||||
}
|
||||
|
||||
+14
-18
@@ -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<R: Runtime> {
|
||||
#[allow(dead_code)]
|
||||
app: AppHandle<R>,
|
||||
pub(crate) struct Http {
|
||||
#[cfg(feature = "cookies")]
|
||||
cookies_jar: std::sync::Arc<reqwest::cookie::Jar>,
|
||||
}
|
||||
|
||||
/* trait HttpExt<R: Runtime> {
|
||||
fn http(&self) -> &Http<R>;
|
||||
}
|
||||
|
||||
impl<R: Runtime, T: Manager<R>> HttpExt<R> for T {
|
||||
fn http(&self) -> &Http<R> {
|
||||
self.state::<Http<R>>().inner()
|
||||
}
|
||||
} */
|
||||
|
||||
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||
Builder::<R>::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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user