diff --git a/Cargo.lock b/Cargo.lock index 813f90dc..96cf5b52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -324,6 +324,20 @@ dependencies = [ "futures-core", ] +[[package]] +name = "async-compression" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b74f44609f0f91493e3082d3734d98497e094777144380ea4db9f9905dd5b6" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + [[package]] name = "async-executor" version = "1.5.1" @@ -366,7 +380,7 @@ dependencies = [ "polling", "rustix", "slab", - "socket2", + "socket2 0.4.9", "waker-fn", ] @@ -982,6 +996,34 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "cookie" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" +dependencies = [ + "percent-encoding", + "time 0.3.21", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d606d0fba62e13cf04db20536c05cb7f13673c161cb47a47a82b9b9e7d3f1daa" +dependencies = [ + "cookie", + "idna 0.2.3", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time 0.3.21", + "url", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -1215,6 +1257,12 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +[[package]] +name = "data-url" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41b319d1b62ffbd002e057f36bebd1f42b9f97927c9577461d855f3513c4289f" + [[package]] name = "der" version = "0.5.1" @@ -1402,6 +1450,18 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enum-as-inner" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "enumflags2" version = "0.7.7" @@ -1565,9 +1625,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] @@ -2086,6 +2146,34 @@ dependencies = [ "tracing", ] +[[package]] +name = "h3" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6de6ca43eed186fd055214af06967b0a7a68336cefec7e8a4004e96efeaccb9e" +dependencies = [ + "bytes 1.4.0", + "fastrand", + "futures-util", + "http", + "tokio", + "tracing", +] + +[[package]] +name = "h3-quinn" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d4a1a1763e4f3e82ee9f1ecf2cf862b22cc7316ebe14684e42f94532b5ec64d" +dependencies = [ + "bytes 1.4.0", + "futures", + "h3", + "quinn", + "quinn-proto", + "tokio-util", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -2179,6 +2267,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + [[package]] name = "html5ever" version = "0.25.2" @@ -2250,7 +2349,7 @@ dependencies = [ "httpdate", "itoa 1.0.6", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -2332,6 +2431,17 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "idna" version = "0.3.0" @@ -2342,6 +2452,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "ignore" version = "0.4.20" @@ -2514,6 +2634,18 @@ dependencies = [ "libc", ] +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2 0.5.3", + "widestring", + "windows-sys 0.48.0", + "winreg 0.50.0", +] + [[package]] name = "ipnet" version = "2.7.2" @@ -2792,6 +2924,12 @@ dependencies = [ "safemem", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.3.8" @@ -2833,6 +2971,15 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "mac" version = "0.1.1" @@ -2875,6 +3022,12 @@ dependencies = [ "tendril", ] +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + [[package]] name = "matchers" version = "0.1.0" @@ -3520,9 +3673,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "phf" @@ -3821,6 +3974,22 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "publicsuffix" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" +dependencies = [ + "idna 0.3.0", + "psl-types", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -3845,6 +4014,53 @@ dependencies = [ "memchr", ] +[[package]] +name = "quinn" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +dependencies = [ + "bytes 1.4.0", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls 0.21.1", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c8bb234e70c863204303507d841e7fa2295e95c822b2bb4ca8ebf57f17b1cb" +dependencies = [ + "bytes 1.4.0", + "rand 0.8.5", + "ring", + "rustc-hash", + "rustls 0.21.1", + "slab", + "thiserror", + "tinyvec", + "tracing", +] + +[[package]] +name = "quinn-udp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6df19e284d93757a9fb91d63672f7741b129246a669db09d1c0063071debc0c0" +dependencies = [ + "bytes 1.4.0", + "libc", + "socket2 0.5.3", + "tracing", + "windows-sys 0.48.0", +] + [[package]] name = "quote" version = "1.0.28" @@ -4019,12 +4235,18 @@ version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ + "async-compression", "base64 0.21.2", "bytes 1.4.0", + "cookie", + "cookie_store", "encoding_rs", + "futures-channel", "futures-core", "futures-util", "h2", + "h3", + "h3-quinn", "http", "http-body", "hyper", @@ -4039,7 +4261,9 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "quinn", "rustls 0.21.1", + "rustls-native-certs", "rustls-pemfile", "serde", "serde_json", @@ -4047,8 +4271,10 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls 0.24.0", + "tokio-socks", "tokio-util", "tower-service", + "trust-dns-resolver", "url", "wasm-bindgen", "wasm-bindgen-futures", @@ -4058,6 +4284,16 @@ dependencies = [ "winreg 0.10.1", ] +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + [[package]] name = "rfd" version = "0.11.4" @@ -4136,6 +4372,12 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc_version" version = "0.4.0" @@ -4183,6 +4425,18 @@ dependencies = [ "sct", ] +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.2" @@ -4544,6 +4798,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "soup3" version = "0.3.2" @@ -5218,17 +5482,16 @@ dependencies = [ name = "tauri-plugin-http" version = "2.0.0-alpha.0" dependencies = [ - "bytes 1.4.0", + "data-url", "glob", "http", - "rand 0.8.5", "reqwest", "serde", "serde_json", - "serde_repr", "tauri", "tauri-plugin-fs", "thiserror", + "url", ] [[package]] @@ -5740,7 +6003,7 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", - "socket2", + "socket2 0.4.9", "windows-sys 0.48.0", ] @@ -5775,6 +6038,18 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-socks" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0" +dependencies = [ + "either", + "futures-util", + "thiserror", + "tokio", +] + [[package]] name = "tokio-stream" version = "0.1.14" @@ -5941,6 +6216,51 @@ dependencies = [ "serde_json", ] +[[package]] +name = "trust-dns-proto" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.2.3", + "ipnet", + "lazy_static", + "rand 0.8.5", + "smallvec", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" +dependencies = [ + "cfg-if", + "futures-util", + "ipconfig", + "lazy_static", + "lru-cache", + "parking_lot 0.12.1", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "tracing", + "trust-dns-proto", +] + [[package]] name = "try-lock" version = "0.2.4" @@ -6072,12 +6392,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", - "idna", + "idna 0.4.0", "percent-encoding", "serde", ] @@ -6431,6 +6751,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "widestring" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" + [[package]] name = "win7-notifications" version = "0.3.1" @@ -6831,6 +7157,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "wry" version = "0.28.3" diff --git a/examples/api/src/views/Http.svelte b/examples/api/src/views/Http.svelte index 998392ed..b17559e2 100644 --- a/examples/api/src/views/Http.svelte +++ b/examples/api/src/views/Http.svelte @@ -18,12 +18,14 @@ (httpBody.startsWith("{") && httpBody.endsWith("}")) || (httpBody.startsWith("[") && httpBody.endsWith("]")) ) { - options.body = JSON.parse(httpBody) + options.body = JSON.parse(httpBody); } else if (httpBody !== "") { - options.body = httpBody + options.body = httpBody; } - tauriFetch("http://localhost:3003", options).then(onMessage).catch(onMessage); + tauriFetch("http://localhost:3003", options) + .then(onMessage) + .catch(onMessage); } /// http form @@ -33,7 +35,7 @@ let multipart = true; async function doPost() { - result = await tauriFetch("http://localhost:3003", { + const response = await tauriFetch("http://localhost:3003", { method: "POST", body: { foo, @@ -43,6 +45,11 @@ ? { "Content-Type": "multipart/form-data" } : undefined, }); + result = { + status: response.status, + headers: JSON.parse(JSON.stringify(response.headers)), + body: response.body, + }; } diff --git a/plugins/http/guest-js/index.ts b/plugins/http/guest-js/index.ts index 88622130..8c1ea94e 100644 --- a/plugins/http/guest-js/index.ts +++ b/plugins/http/guest-js/index.ts @@ -68,8 +68,8 @@ export async function fetch( // Remove these fields before creating the request if (init) { - init.maxRedirections = undefined; - init.connectTimeout = undefined; + delete init.maxRedirections; + delete init.connectTimeout; } const req = new Request(input, init); @@ -104,6 +104,7 @@ export async function fetch( await window.__TAURI_INVOKE__("plugin:http|fetch_send", { rid, }); + console.log(status, url, headers, data) const res = new Response(Uint8Array.from(data), { headers, diff --git a/plugins/http/src/api-iife.js b/plugins/http/src/api-iife.js index 0944fcd0..7a161d75 100644 --- a/plugins/http/src/api-iife.js +++ b/plugins/http/src/api-iife.js @@ -1 +1 @@ -if("__TAURI__"in window){var __TAURI_HTTP__=function(t){"use strict";return t.fetch=async function(t,e){const n=null==e?void 0:e.maxRedirections,r=null==e?void 0:e.maxRedirections;e&&(e.maxRedirections=void 0,e.connectTimeout=void 0);const i=new Request(t,e),a=await i.arrayBuffer(),_=a.byteLength?Array.from(new Uint8Array(a)):null,o=await window.__TAURI_INVOKE__("plugin:http|fetch",{cmd:"fetch",method:i.method,url:i.url,headers:Array.from(i.headers.entries()),data:_,maxRedirections:n,connectTimeout:r});i.signal.addEventListener("abort",(()=>{window.__TAURI_INVOKE__("plugin:http|fetch_cancel",{rid:o})}));const{status:d,statusText:s,url:c,headers:u,data:l}=await window.__TAURI_INVOKE__("plugin:http|fetch_send",{rid:o}),h=new Response(Uint8Array.from(l),{headers:u,status:d,statusText:s});return Object.defineProperty(h,"url",{value:c}),h},t}({});Object.defineProperty(window.__TAURI__,"http",{value:__TAURI_HTTP__})} +if("__TAURI__"in window){var __TAURI_HTTP__=function(e){"use strict";return e.fetch=async function(e,t){const n=null==t?void 0:t.maxRedirections,r=null==t?void 0:t.maxRedirections;t&&(delete t.maxRedirections,delete t.connectTimeout);const i=new Request(e,t),a=await i.arrayBuffer(),_=a.byteLength?Array.from(new Uint8Array(a)):null,o=await window.__TAURI_INVOKE__("plugin:http|fetch",{cmd:"fetch",method:i.method,url:i.url,headers:Array.from(i.headers.entries()),data:_,maxRedirections:n,connectTimeout:r});i.signal.addEventListener("abort",(()=>{window.__TAURI_INVOKE__("plugin:http|fetch_cancel",{rid:o})}));const{status:s,statusText:d,url:c,headers:u,data:l}=await window.__TAURI_INVOKE__("plugin:http|fetch_send",{rid:o});console.log(s,c,u,l);const h=new Response(Uint8Array.from(l),{headers:u,status:s,statusText:d});return Object.defineProperty(h,"url",{value:c}),h},e}({});Object.defineProperty(window.__TAURI__,"http",{value:__TAURI_HTTP__})} diff --git a/plugins/http/src/commands.rs b/plugins/http/src/commands.rs index 93a3adde..3bc23976 100644 --- a/plugins/http/src/commands.rs +++ b/plugins/http/src/commands.rs @@ -14,13 +14,12 @@ use crate::{Error, FetchRequest, FetchResponse, HttpExt, RequestId}; pub(crate) async fn fetch( app: AppHandle, method: String, - url: String, + url: url::Url, headers: Vec<(String, String)>, data: Option>, - connect_timeout: u64, - max_redirections: usize, + connect_timeout: Option, + max_redirections: Option, ) -> crate::Result { - let url = url::Url::parse(&url)?; let scheme = url.scheme(); let method = Method::from_bytes(method.as_bytes())?; let headers: HashMap = HashMap::from_iter(headers); @@ -28,11 +27,21 @@ pub(crate) async fn fetch( match scheme { "http" | "https" => { if app.http().scope.is_allowed(&url) { - let mut request = reqwest::ClientBuilder::new() - .connect_timeout(Duration::from_millis(connect_timeout)) - .redirect(Policy::limited(max_redirections)) - .build()? - .request(method.clone(), url); + let mut builder = reqwest::ClientBuilder::new(); + + if let Some(timeout) = connect_timeout { + builder = builder.connect_timeout(Duration::from_millis(timeout)); + } + + if let Some(max_redirections) = max_redirections { + builder = builder.redirect(if max_redirections == 0 { + Policy::none() + } else { + Policy::limited(max_redirections) + }); + } + + let mut request = builder.build()?.request(method.clone(), url); for (key, value) in &headers { let name = HeaderName::from_bytes(key.as_bytes())?; diff --git a/plugins/http/src/lib.rs b/plugins/http/src/lib.rs index 7e6d4456..d86745cc 100644 --- a/plugins/http/src/lib.rs +++ b/plugins/http/src/lib.rs @@ -29,13 +29,15 @@ type RequestId = u32; type CancelableResponseResult = Result>; type CancelableResponseFuture = Pin + Send + Sync>>; +type RequestTable = HashMap; + struct FetchRequest(Mutex); impl FetchRequest { fn new(f: CancelableResponseFuture) -> Self { Self(Mutex::new(f)) } } -type RequestTable = HashMap; + #[derive(Serialize)] #[serde(rename_all = "camelCase")] struct FetchResponse {