From 2a338458b955d0da913aed614f7dd367a93d4494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 6 Oct 2023 11:26:51 +0100 Subject: [PATCH] fixed request timeouts for wasm --- Cargo.toml | 2 +- common/http-api-client/Cargo.toml | 7 +- common/http-api-client/src/lib.rs | 115 +++++++++++++++++++---- ephemera/Cargo.toml | 2 +- nym-connect/desktop/Cargo.lock | 52 +++++++--- nym-connect/desktop/src-tauri/Cargo.toml | 2 +- nym-wallet/src-tauri/Cargo.toml | 2 +- 7 files changed, 144 insertions(+), 38 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f3ce3e1322..2dea7b7f35 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -161,7 +161,7 @@ log = "0.4" once_cell = "1.7.2" parking_lot = "0.12.1" rand = "0.8.5" -reqwest = "0.11.18" +reqwest = "0.11.22" schemars = "0.8.1" serde = "1.0.152" serde_json = "1.0.91" diff --git a/common/http-api-client/Cargo.toml b/common/http-api-client/Cargo.toml index 7b784149a5..ac43b59576 100644 --- a/common/http-api-client/Cargo.toml +++ b/common/http-api-client/Cargo.toml @@ -17,4 +17,9 @@ url = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } -tracing = { workspace = true } \ No newline at end of file +tracing = { workspace = true } + +# for request timeout until https://github.com/seanmonstar/reqwest/issues/1135 is fixed +[target."cfg(target_arch = \"wasm32\")".dependencies.wasmtimer] +workspace = true +features = ["tokio"] \ No newline at end of file diff --git a/common/http-api-client/src/lib.rs b/common/http-api-client/src/lib.rs index 7ebefd4ba0..8bb81c2450 100644 --- a/common/http-api-client/src/lib.rs +++ b/common/http-api-client/src/lib.rs @@ -46,6 +46,10 @@ pub enum HttpClientError { #[error("failed to resolve request. status: '{status}', additional error message: {error}")] EndpointFailure { status: StatusCode, error: E }, + + #[cfg(target_arch = "wasm32")] + #[error("the request has timed out")] + RequestTimeout, } /// A simple extendable client wrapper for http request with extra url sanitization. @@ -53,19 +57,31 @@ pub enum HttpClientError { pub struct Client { base_url: Url, reqwest_client: reqwest::Client, + + #[cfg(target_arch = "wasm32")] + request_timeout: Duration, } impl Client { + // no timeout until https://github.com/seanmonstar/reqwest/issues/1135 is fixed pub fn new(base_url: Url, timeout: Option) -> Self { + #[cfg(target_arch = "wasm32")] + let reqwest_client = reqwest::Client::new(); + + // TODO: we should probably be propagating the error rather than panicking, + // but that'd break bunch of things due to type changes + #[cfg(not(target_arch = "wasm32"))] + let reqwest_client = reqwest::ClientBuilder::new() + .timeout(timeout.unwrap_or(DEFAULT_TIMEOUT)) + .build() + .expect("Client::new()"); + Client { base_url, + reqwest_client, - // TODO: we should probably be propagating the error rather than panicking, - // but that'd break bunch of things due to type changes - reqwest_client: reqwest::ClientBuilder::new() - .timeout(timeout.unwrap_or(DEFAULT_TIMEOUT)) - .build() - .expect("Client::new()"), + #[cfg(target_arch = "wasm32")] + request_timeout: timeout.unwrap_or(DEFAULT_TIMEOUT), } } @@ -106,7 +122,23 @@ impl Client { E: Display, { let url = sanitize_url(&self.base_url, path, params); - Ok(self.reqwest_client.get(url).send().await?) + + #[cfg(target_arch = "wasm32")] + { + Ok( + wasmtimer::tokio::timeout( + self.request_timeout, + self.reqwest_client.get(url).send(), + ) + .await + .map_err(|_timeout| HttpClientError::RequestTimeout)??, + ) + } + + #[cfg(not(target_arch = "wasm32"))] + { + Ok(self.reqwest_client.get(url).send().await?) + } } async fn send_post_request( @@ -122,7 +154,21 @@ impl Client { E: Display, { let url = sanitize_url(&self.base_url, path, params); - Ok(self.reqwest_client.post(url).json(json_body).send().await?) + + #[cfg(target_arch = "wasm32")] + { + Ok(wasmtimer::tokio::timeout( + self.request_timeout, + self.reqwest_client.post(url).json(json_body).send(), + ) + .await + .map_err(|_timeout| HttpClientError::RequestTimeout)??) + } + + #[cfg(not(target_arch = "wasm32"))] + { + Ok(self.reqwest_client.post(url).json(json_body).send().await?) + } } pub async fn get_json( @@ -163,11 +209,26 @@ impl Client { E: Display + DeserializeOwned, S: AsRef, { - let res = self - .reqwest_client - .get(self.base_url.join(endpoint.as_ref())?) - .send() - .await?; + #[cfg(target_arch = "wasm32")] + let res = { + wasmtimer::tokio::timeout( + self.request_timeout, + self.reqwest_client + .get(self.base_url.join(endpoint.as_ref())?) + .send(), + ) + .await + .map_err(|_timeout| HttpClientError::RequestTimeout)?? + }; + + #[cfg(not(target_arch = "wasm32"))] + let res = { + self.reqwest_client + .get(self.base_url.join(endpoint.as_ref())?) + .send() + .await? + }; + parse_response(res, false).await } @@ -182,12 +243,28 @@ impl Client { E: Display + DeserializeOwned, S: AsRef, { - let res = self - .reqwest_client - .post(self.base_url.join(endpoint.as_ref())?) - .json(json_body) - .send() - .await?; + #[cfg(target_arch = "wasm32")] + let res = { + wasmtimer::tokio::timeout( + self.request_timeout, + self.reqwest_client + .post(self.base_url.join(endpoint.as_ref())?) + .json(json_body) + .send(), + ) + .await + .map_err(|_timeout| HttpClientError::RequestTimeout)?? + }; + + #[cfg(not(target_arch = "wasm32"))] + let res = { + self.reqwest_client + .post(self.base_url.join(endpoint.as_ref())?) + .json(json_body) + .send() + .await? + }; + parse_response(res, true).await } } diff --git a/ephemera/Cargo.toml b/ephemera/Cargo.toml index fae4142e67..63ccaa9ab7 100644 --- a/ephemera/Cargo.toml +++ b/ephemera/Cargo.toml @@ -36,7 +36,7 @@ nym-config = { path = "../common/config" } nym-ephemera-common = { path = "../common/cosmwasm-smart-contracts/ephemera" } pretty_env_logger = "0.4" refinery = { version = "0.8.7", features = ["rusqlite"], optional = true } -reqwest = { version = "0.11.6", features = ["json"] } +reqwest = { version = "0.11.22", features = ["json"] } # Rocksdb kills compilation times and we're not currently using it. The reason # we comment it out is that rust-analyzer runs with --all-features #rocksdb = { version = "0.21.0", optional = true } diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 2dc02927e3..50866ab4f1 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -2975,6 +2975,7 @@ dependencies = [ "thiserror", "tracing", "url", + "wasmtimer", ] [[package]] @@ -5627,9 +5628,9 @@ checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ "base64 0.21.2", "bytes", @@ -5652,6 +5653,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-native-tls", "tokio-socks", @@ -5662,7 +5664,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "winreg 0.10.1", + "winreg 0.50.0", ] [[package]] @@ -6862,6 +6864,27 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system-deps" version = "5.0.0" @@ -7992,9 +8015,9 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasm-streams" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" dependencies = [ "futures-util", "js-sys", @@ -8456,15 +8479,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - [[package]] name = "winreg" version = "0.11.0" @@ -8475,6 +8489,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.24.3" diff --git a/nym-connect/desktop/src-tauri/Cargo.toml b/nym-connect/desktop/src-tauri/Cargo.toml index 3947434d65..193d3a53a3 100644 --- a/nym-connect/desktop/src-tauri/Cargo.toml +++ b/nym-connect/desktop/src-tauri/Cargo.toml @@ -31,7 +31,7 @@ log = { version = "0.4", features = ["serde"] } pretty_env_logger = "0.4.0" rand = "0.8" rand-07 = { package = "rand", version = "0.7.3" } -reqwest = { version = "0.11.18", features = ["json", "socks"] } +reqwest = { version = "0.11.22", features = ["json", "socks"] } rust-embed = { version = "6.4.2", features = ["include-exclude"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index a7145c9282..aceef1f9b8 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -32,7 +32,7 @@ itertools = "0.10" log = { version = "0.4", features = ["serde"] } once_cell = "1.7.2" pretty_env_logger = "0.4" -reqwest = {version = "0.11.18", features = ["json"] } +reqwest = {version = "0.11.22", features = ["json"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_repr = "0.1"