From 88ca172fadf201e4003a32de659f8970e3f750c0 Mon Sep 17 00:00:00 2001 From: dumko2001 Date: Wed, 18 Mar 2026 13:37:31 +0530 Subject: [PATCH 1/7] fix(client): add connect and request timeouts --- src/client.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/client.rs b/src/client.rs index e0abe409..0f2f99fc 100644 --- a/src/client.rs +++ b/src/client.rs @@ -13,6 +13,8 @@ pub fn build_client() -> Result { reqwest::Client::builder() .default_headers(headers) + .connect_timeout(std::time::Duration::from_secs(10)) + .timeout(std::time::Duration::from_secs(120)) .build() .map_err(|e| { crate::error::GwsError::Other(anyhow::anyhow!("Failed to build HTTP client: {e}")) From 2b4028070d744e9649989aec78e365cee9f20145 Mon Sep 17 00:00:00 2001 From: dumko2001 Date: Wed, 18 Mar 2026 14:16:06 +0530 Subject: [PATCH 2/7] chore: add changeset for http timeouts --- .changeset/http-timeouts.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 .changeset/http-timeouts.md diff --git a/.changeset/http-timeouts.md b/.changeset/http-timeouts.md new file mode 100644 index 00000000..b5dbe35a --- /dev/null +++ b/.changeset/http-timeouts.md @@ -0,0 +1 @@ +---\n"gws": patch\n---\n\nfix(client): add 10s connect and 120s request timeouts to prevent indefinite hangs From c2a8e20b589427eef2252bc093432d4f0d29153b Mon Sep 17 00:00:00 2001 From: dumko2001 Date: Wed, 18 Mar 2026 14:20:02 +0530 Subject: [PATCH 3/7] chore: add changeset for http timeouts --- .changeset/http-timeouts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/http-timeouts.md b/.changeset/http-timeouts.md index b5dbe35a..086dfb8c 100644 --- a/.changeset/http-timeouts.md +++ b/.changeset/http-timeouts.md @@ -1 +1 @@ ----\n"gws": patch\n---\n\nfix(client): add 10s connect and 120s request timeouts to prevent indefinite hangs +---\n"gws": patch\n---\n\nfix(client): add connect and request timeouts to prevent indefinite hangs From bd0879aea0da6f76f3d65196fd3ac156a573d74a Mon Sep 17 00:00:00 2001 From: dumko2001 Date: Wed, 18 Mar 2026 14:29:48 +0530 Subject: [PATCH 4/7] refactor(client): use named constants for timeouts --- src/client.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/client.rs b/src/client.rs index 0f2f99fc..55b31a78 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,5 +1,12 @@ use reqwest::header::{HeaderMap, HeaderValue}; +const MAX_RETRIES: u32 = 3; +/// Maximum seconds to sleep on a 429 Retry-After header. Prevents a hostile +/// or misconfigured server from hanging the process indefinitely. +const MAX_RETRY_DELAY_SECS: u64 = 60; +const CONNECT_TIMEOUT_SECS: u64 = 10; +const REQUEST_TIMEOUT_SECS: u64 = 120; + pub fn build_client() -> Result { let mut headers = HeaderMap::new(); let name = env!("CARGO_PKG_NAME"); @@ -13,19 +20,14 @@ pub fn build_client() -> Result { reqwest::Client::builder() .default_headers(headers) - .connect_timeout(std::time::Duration::from_secs(10)) - .timeout(std::time::Duration::from_secs(120)) + .connect_timeout(std::time::Duration::from_secs(CONNECT_TIMEOUT_SECS)) + .timeout(std::time::Duration::from_secs(REQUEST_TIMEOUT_SECS)) .build() .map_err(|e| { crate::error::GwsError::Other(anyhow::anyhow!("Failed to build HTTP client: {e}")) }) } -const MAX_RETRIES: u32 = 3; -/// Maximum seconds to sleep on a 429 Retry-After header. Prevents a hostile -/// or misconfigured server from hanging the process indefinitely. -const MAX_RETRY_DELAY_SECS: u64 = 60; - /// Send an HTTP request with automatic retry on 429 (rate limit) responses. /// Respects the `Retry-After` header; falls back to exponential backoff (1s, 2s, 4s). pub async fn send_with_retry( From edfa36489832cbbec9ccde94be421c8d9dbc5816 Mon Sep 17 00:00:00 2001 From: dumko2001 Date: Wed, 18 Mar 2026 15:08:05 +0530 Subject: [PATCH 5/7] chore: correct changeset package name --- .changeset/http-timeouts.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/http-timeouts.md b/.changeset/http-timeouts.md index 086dfb8c..3c36a9b6 100644 --- a/.changeset/http-timeouts.md +++ b/.changeset/http-timeouts.md @@ -1 +1 @@ ----\n"gws": patch\n---\n\nfix(client): add connect and request timeouts to prevent indefinite hangs +---\n"@googleworkspace/cli": patch\n---\n\nfix(client): add connect and request timeouts to prevent indefinite hangs From e3e3a279a53c1834681712db099a52c3b7ee68f7 Mon Sep 17 00:00:00 2001 From: dumko2001 Date: Wed, 18 Mar 2026 15:24:20 +0530 Subject: [PATCH 6/7] fix(client): remove global request timeout and retain connect timeout --- .changeset/http-timeouts.md | 2 +- src/client.rs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.changeset/http-timeouts.md b/.changeset/http-timeouts.md index 3c36a9b6..2ca5a156 100644 --- a/.changeset/http-timeouts.md +++ b/.changeset/http-timeouts.md @@ -1 +1 @@ ----\n"@googleworkspace/cli": patch\n---\n\nfix(client): add connect and request timeouts to prevent indefinite hangs +---\n"@googleworkspace/cli": patch\n---\n\nfix(client): add 10s connect timeout to prevent hangs on initial connection diff --git a/src/client.rs b/src/client.rs index 55b31a78..4024d703 100644 --- a/src/client.rs +++ b/src/client.rs @@ -5,7 +5,6 @@ const MAX_RETRIES: u32 = 3; /// or misconfigured server from hanging the process indefinitely. const MAX_RETRY_DELAY_SECS: u64 = 60; const CONNECT_TIMEOUT_SECS: u64 = 10; -const REQUEST_TIMEOUT_SECS: u64 = 120; pub fn build_client() -> Result { let mut headers = HeaderMap::new(); @@ -21,7 +20,6 @@ pub fn build_client() -> Result { reqwest::Client::builder() .default_headers(headers) .connect_timeout(std::time::Duration::from_secs(CONNECT_TIMEOUT_SECS)) - .timeout(std::time::Duration::from_secs(REQUEST_TIMEOUT_SECS)) .build() .map_err(|e| { crate::error::GwsError::Other(anyhow::anyhow!("Failed to build HTTP client: {e}")) From ac994ca702e4dcb080236378fa68aae469d7687d Mon Sep 17 00:00:00 2001 From: dumko2001 Date: Wed, 18 Mar 2026 16:40:39 +0530 Subject: [PATCH 7/7] fix(client): add generous 10-minute request timeout --- src/client.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/client.rs b/src/client.rs index 4024d703..de94fd4b 100644 --- a/src/client.rs +++ b/src/client.rs @@ -5,6 +5,7 @@ const MAX_RETRIES: u32 = 3; /// or misconfigured server from hanging the process indefinitely. const MAX_RETRY_DELAY_SECS: u64 = 60; const CONNECT_TIMEOUT_SECS: u64 = 10; +const REQUEST_TIMEOUT_SECS: u64 = 600; pub fn build_client() -> Result { let mut headers = HeaderMap::new(); @@ -20,6 +21,7 @@ pub fn build_client() -> Result { reqwest::Client::builder() .default_headers(headers) .connect_timeout(std::time::Duration::from_secs(CONNECT_TIMEOUT_SECS)) + .timeout(std::time::Duration::from_secs(REQUEST_TIMEOUT_SECS)) .build() .map_err(|e| { crate::error::GwsError::Other(anyhow::anyhow!("Failed to build HTTP client: {e}"))