mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-09-22 21:30:44 +02:00
fix(http): include browser headers if not set by user (#1354)
* fix(http): include browser automatic headers if not set by user close #1349 * fmt * Update browser-headers.md * lint * generate api
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"http-js": "patch"
|
||||||
|
---
|
||||||
|
|
||||||
|
Include headers created by browser if not declared by user, which fixes missing headers like `Content-Type` when using `FormData`.
|
||||||
@@ -1 +1 @@
|
|||||||
if("__TAURI__"in window){var __TAURI_PLUGIN_HTTP__=function(e){"use strict";async function t(e,t={},r){return window.__TAURI_INTERNALS__.invoke(e,t,r)}return"function"==typeof SuppressedError&&SuppressedError,e.fetch=async function(e,r){const n=r?.maxRedirections,a=r?.connectTimeout,i=r?.proxy;r&&(delete r.maxRedirections,delete r.connectTimeout,delete r.proxy);const s=r?.signal,o=(r?.headers?r.headers instanceof Headers?Array.from(r.headers.entries()):Array.isArray(r.headers)?r.headers:Object.entries(r.headers):[]).map((([e,t])=>[e,"string"==typeof t?t:t.toString()])),d=new Request(e,r),c=await d.arrayBuffer(),u=0!==c.byteLength?Array.from(new Uint8Array(c)):null,_=await t("plugin:http|fetch",{clientConfig:{method:d.method,url:d.url,headers:o,data:u,maxRedirections:n,connectTimeout:a,proxy:i}});s?.addEventListener("abort",(()=>{t("plugin:http|fetch_cancel",{rid:_})}));const{status:f,statusText:h,url:p,headers:l,rid:y}=await t("plugin:http|fetch_send",{rid:_}),T=await t("plugin:http|fetch_read_body",{rid:y}),w=new Response(T instanceof ArrayBuffer&&0!==T.byteLength?T:T instanceof Array&&T.length>0?new Uint8Array(T):null,{headers:l,status:f,statusText:h});return Object.defineProperty(w,"url",{value:p}),w},e}({});Object.defineProperty(window.__TAURI__,"http",{value:__TAURI_PLUGIN_HTTP__})}
|
if("__TAURI__"in window){var __TAURI_PLUGIN_HTTP__=function(e){"use strict";async function t(e,t={},r){return window.__TAURI_INTERNALS__.invoke(e,t,r)}return"function"==typeof SuppressedError&&SuppressedError,e.fetch=async function(e,r){const n=r?.maxRedirections,a=r?.connectTimeout,s=r?.proxy;r&&(delete r.maxRedirections,delete r.connectTimeout,delete r.proxy);const i=r?.signal,o=r?.headers?r.headers instanceof Headers?r.headers:new Headers(r.headers):new Headers,d=new Request(e,r),c=await d.arrayBuffer(),u=0!==c.byteLength?Array.from(new Uint8Array(c)):null;for(const[e,t]of d.headers)o.get(e)||o.set(e,t);const _=(o instanceof Headers?Array.from(o.entries()):Array.isArray(o)?o:Object.entries(o)).map((([e,t])=>[e,"string"==typeof t?t:t.toString()])),f=await t("plugin:http|fetch",{clientConfig:{method:d.method,url:d.url,headers:_,data:u,maxRedirections:n,connectTimeout:a,proxy:s}});i?.addEventListener("abort",(()=>{t("plugin:http|fetch_cancel",{rid:f})}));const{status:h,statusText:p,url:l,headers:y,rid:w}=await t("plugin:http|fetch_send",{rid:f}),T=await t("plugin:http|fetch_read_body",{rid:w}),A=new Response(T instanceof ArrayBuffer&&0!==T.byteLength?T:T instanceof Array&&T.length>0?new Uint8Array(T):null,{headers:y,status:h,statusText:p});return Object.defineProperty(A,"url",{value:l}),A},e}({});Object.defineProperty(window.__TAURI__,"http",{value:__TAURI_PLUGIN_HTTP__})}
|
||||||
|
|||||||
@@ -117,30 +117,45 @@ export async function fetch(
|
|||||||
|
|
||||||
const headers = init?.headers
|
const headers = init?.headers
|
||||||
? init.headers instanceof Headers
|
? init.headers instanceof Headers
|
||||||
? Array.from(init.headers.entries())
|
? init.headers
|
||||||
: Array.isArray(init.headers)
|
: new Headers(init.headers)
|
||||||
? init.headers
|
: new Headers();
|
||||||
: Object.entries(init.headers)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const mappedHeaders: Array<[string, string]> = headers.map(([name, val]) => [
|
|
||||||
name,
|
|
||||||
// we need to ensure we have all values as strings
|
|
||||||
// eslint-disable-next-line
|
|
||||||
typeof val === "string" ? val : (val as any).toString(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const req = new Request(input, init);
|
const req = new Request(input, init);
|
||||||
const buffer = await req.arrayBuffer();
|
const buffer = await req.arrayBuffer();
|
||||||
const reqData =
|
const data =
|
||||||
buffer.byteLength !== 0 ? Array.from(new Uint8Array(buffer)) : null;
|
buffer.byteLength !== 0 ? Array.from(new Uint8Array(buffer)) : null;
|
||||||
|
|
||||||
|
// append new headers created by the browser `Request` implementation,
|
||||||
|
// if not already declared by the caller of this function
|
||||||
|
for (const [key, value] of req.headers) {
|
||||||
|
if (!headers.get(key)) {
|
||||||
|
headers.set(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const headersArray =
|
||||||
|
headers instanceof Headers
|
||||||
|
? Array.from(headers.entries())
|
||||||
|
: Array.isArray(headers)
|
||||||
|
? headers
|
||||||
|
: Object.entries(headers);
|
||||||
|
|
||||||
|
const mappedHeaders: Array<[string, string]> = headersArray.map(
|
||||||
|
([name, val]) => [
|
||||||
|
name,
|
||||||
|
// we need to ensure we have all header values as strings
|
||||||
|
// eslint-disable-next-line
|
||||||
|
typeof val === "string" ? val : (val as any).toString(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
const rid = await invoke<number>("plugin:http|fetch", {
|
const rid = await invoke<number>("plugin:http|fetch", {
|
||||||
clientConfig: {
|
clientConfig: {
|
||||||
method: req.method,
|
method: req.method,
|
||||||
url: req.url,
|
url: req.url,
|
||||||
headers: mappedHeaders,
|
headers: mappedHeaders,
|
||||||
data: reqData,
|
data,
|
||||||
maxRedirections,
|
maxRedirections,
|
||||||
connectTimeout,
|
connectTimeout,
|
||||||
proxy,
|
proxy,
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ pub struct FetchResponse {
|
|||||||
rid: ResourceId,
|
rid: ResourceId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ClientConfig {
|
pub struct ClientConfig {
|
||||||
method: String,
|
method: String,
|
||||||
@@ -57,7 +57,7 @@ pub struct ClientConfig {
|
|||||||
proxy: Option<Proxy>,
|
proxy: Option<Proxy>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Proxy {
|
pub struct Proxy {
|
||||||
all: Option<UrlOrConfig>,
|
all: Option<UrlOrConfig>,
|
||||||
@@ -65,7 +65,7 @@ pub struct Proxy {
|
|||||||
https: Option<UrlOrConfig>,
|
https: Option<UrlOrConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum UrlOrConfig {
|
pub enum UrlOrConfig {
|
||||||
@@ -73,7 +73,7 @@ pub enum UrlOrConfig {
|
|||||||
Config(ProxyConfig),
|
Config(ProxyConfig),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ProxyConfig {
|
pub struct ProxyConfig {
|
||||||
url: String,
|
url: String,
|
||||||
@@ -81,7 +81,7 @@ pub struct ProxyConfig {
|
|||||||
no_proxy: Option<String>,
|
no_proxy: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct BasicAuth {
|
pub struct BasicAuth {
|
||||||
username: String,
|
username: String,
|
||||||
password: String,
|
password: String,
|
||||||
|
|||||||
Reference in New Issue
Block a user