From 6849006ad799dce7a55384ef88ab5491e8ce3efc Mon Sep 17 00:00:00 2001 From: YoursFunny Date: Sat, 8 Aug 2026 20:05:51 +0800 Subject: [PATCH] site: honor TELOXIDE_PROXY for site fetches The shared HTTP client ignored the proxy the Bot API uses, so on proxy-required networks (e.g. behind the GFW) every site fetch failed while the bot itself worked. Explicit proxy overrides reqwest's system detection; unset keeps direct connections. --- crates/x-media/src/site/mod.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/crates/x-media/src/site/mod.rs b/crates/x-media/src/site/mod.rs index 5dc4cb9..5eb733b 100644 --- a/crates/x-media/src/site/mod.rs +++ b/crates/x-media/src/site/mod.rs @@ -203,12 +203,22 @@ impl From for FetchError { /// Shared HTTP client (browser User-Agent) for twitter/bsky fetches and /// [`download_media`]. pub(crate) static CLIENT: LazyLock = LazyLock::new(|| { - let builder = reqwest::Client::builder() + let mut builder = reqwest::Client::builder() .user_agent("Mozilla/5.0") // reqwest has no total timeout by default; a stalled connection // would otherwise pin a fetch/handler forever. .timeout(Duration::from_secs(30)) .connect_timeout(Duration::from_secs(10)); + // Route site fetches through the same proxy the Bot API uses, so a + // network that needs TELOXIDE_PROXY (e.g. behind the GFW) does not + // leave site fetches dead while the bot itself works. + if let Some(proxy) = std::env::var("TELOXIDE_PROXY") + .ok() + .filter(|s| !s.is_empty()) + && let Ok(p) = reqwest::Proxy::all(&proxy) + { + builder = builder.proxy(p); + } // Each `#[tokio::test]` runs on its own runtime; the connection pool is // bound to the runtime that created it, so cross-runtime reuse of idle // connections fails with DispatchGone. In test builds every request uses