From 57499f1d3964c3796bf6a56228f54a919974d553 Mon Sep 17 00:00:00 2001 From: KaraZajac Date: Mon, 23 Feb 2026 17:27:15 -0500 Subject: [PATCH 1/2] Working proxy --- Cargo.lock | 46 +++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 ++++ config.example.toml | 5 +++++ docs/iamb.5 | 27 ++++++++++++++++++++++++++ src/config.rs | 27 ++++++++++++++++++++++++++ src/tests.rs | 2 ++ src/worker.rs | 15 +++++++++++---- 7 files changed, 122 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3810ed04..eb4f774a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1539,6 +1539,15 @@ dependencies = [ "phf 0.11.3", ] +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "endian-type" version = "0.1.2" @@ -2389,9 +2398,11 @@ dependencies = [ "percent-encoding", "pin-project-lite", "socket2 0.6.1", + "system-configuration", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] @@ -2430,6 +2441,7 @@ dependencies = [ "ratatui", "ratatui-image", "regex", + "reqwest", "rpassword", "serde", "serde_json", @@ -4698,6 +4710,7 @@ checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64", "bytes", + "encoding_rs", "futures-core", "futures-util", "h2", @@ -4710,6 +4723,7 @@ dependencies = [ "hyper-util", "js-sys", "log", + "mime", "native-tls", "percent-encoding", "pin-project-lite", @@ -5573,6 +5587,27 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.10.0", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tauri-winrt-notification" version = "0.1.3" @@ -6645,6 +6680,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + [[package]] name = "windows-result" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 19f54cd3..384e1edc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,6 +94,10 @@ version = "0.14.0" default-features = false features = ["e2e-encryption", "sqlite", "sso-login"] +[dependencies.reqwest] +version = "0.12" +features = ["socks"] + [dependencies.tokio] version = "1.24.1" features = ["macros", "net", "rt-multi-thread", "sync", "time"] diff --git a/config.example.toml b/config.example.toml index c4ebd653..addc52c4 100644 --- a/config.example.toml +++ b/config.example.toml @@ -52,6 +52,11 @@ split = [ [macros."normal|visual"] "V" = "m" +[proxy] +# SOCKS5 proxy URL for all Matrix HTTP traffic (requires reqwest socks feature). +# Omit this section or leave unset to use no proxy (or the system proxy from ALL_PROXY). +# url = "socks5://127.0.0.1:1080" + [dirs] cache = "/home/user/.cache/iamb/" logs = "/home/user/.local/share/iamb/logs/" diff --git a/docs/iamb.5 b/docs/iamb.5 index 8357f965..8d1f068a 100644 --- a/docs/iamb.5 +++ b/docs/iamb.5 @@ -66,7 +66,32 @@ Configure the directories to use for data, logs, and more. See .Sx DIRECTORIES for the possible values you can set in this object. +.It Sy proxy +Configure an HTTP/SOCKS proxy for Matrix traffic. +See +.Sx PROXY . +.El +.Sh PROXY +The +.Sy [proxy] +section configures a proxy for all outgoing Matrix HTTP requests. +If unset, no proxy is used for the built-in client (environment variables +such as +.Ev ALL_PROXY +are not read by default). +.Bl -tag -width Ds +.It Sy url +Proxy URL, e.g. +.Dq socks5://127.0.0.1:1080 +for a SOCKS5 proxy. +Requires the reqwest +.Sy socks +feature (enabled in this build). .El +.Pp +.Sy proxy +can be overridden per profile under +.Sx PROFILES . .Sh PROFILES These options are configured as fields in the .Sy profiles @@ -94,6 +119,8 @@ per-profile overrides of their global values: .Sy macros .It .Sy settings +.It +.Sy proxy .El .Ss Example 1: A single profile .Bd -literal -offset indent diff --git a/src/config.rs b/src/config.rs index e7a4a47b..a4f83fe7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -809,6 +809,20 @@ pub enum WindowLayout { Split { split: Vec }, } +#[derive(Clone, Default, Deserialize)] +pub struct ProxyConfig { + /// Proxy URL (e.g. socks5://127.0.0.1:1080). Requires reqwest's socks feature. + pub url: Option, +} + +impl ProxyConfig { + fn merge(self, other: Self) -> Self { + ProxyConfig { + url: self.url.or(other.url), + } + } +} + #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)] #[serde(rename_all = "lowercase", tag = "style")] pub enum Layout { @@ -831,6 +845,7 @@ pub struct ProfileConfig { pub dirs: Option, pub layout: Option, pub macros: Option, + pub proxy: Option, } #[derive(Clone, Deserialize)] @@ -841,6 +856,7 @@ pub struct IambConfig { pub dirs: Option, pub layout: Option, pub macros: Option, + pub proxy: Option, } impl IambConfig { @@ -872,6 +888,8 @@ pub struct ApplicationSettings { pub dirs: DirectoryValues, pub layout: Layout, pub macros: Macros, + /// Proxy URL for the HTTP client (e.g. socks5://127.0.0.1:1080), from [proxy] url. + pub proxy_url: Option, } impl ApplicationSettings { @@ -915,6 +933,7 @@ impl ApplicationSettings { settings: global, layout, macros, + proxy: global_proxy, } = config; validate_profile_names(&profiles); @@ -959,6 +978,13 @@ impl ApplicationSettings { let macros = merge_maps(profile.macros.take(), macros).unwrap_or_default(); let layout = profile.layout.take().or(layout).unwrap_or_default(); + let proxy_url = profile + .proxy + .take() + .unwrap_or_default() + .merge(global_proxy.unwrap_or_default()) + .url; + let tunables = global.unwrap_or_default(); let tunables = profile.settings.take().unwrap_or_default().merge(tunables); let tunables = tunables.values(); @@ -1011,6 +1037,7 @@ impl ApplicationSettings { dirs, layout, macros, + proxy_url, }; Ok(settings) diff --git a/src/tests.rs b/src/tests.rs index e9b05021..121ee846 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -221,11 +221,13 @@ pub fn mock_settings() -> ApplicationSettings { dirs: None, layout: None, macros: None, + proxy: None, }, tunables: mock_tunables(), dirs: mock_dirs(), layout: Default::default(), macros: HashMap::default(), + proxy_url: None, } } diff --git a/src/worker.rs b/src/worker.rs index f3c9791a..fe3964e5 100644 --- a/src/worker.rs +++ b/src/worker.rs @@ -711,14 +711,21 @@ async fn create_client_inner( let req_timeout = Duration::from_secs(settings.tunables.request_timeout); // Set up the HTTP client. - let http = reqwest::Client::builder() + let mut builder = reqwest::Client::builder() .user_agent(IAMB_USER_AGENT) .timeout(req_timeout) .pool_idle_timeout(Duration::from_secs(60)) .pool_max_idle_per_host(10) - .tcp_keepalive(Duration::from_secs(10)) - .build() - .unwrap(); + .tcp_keepalive(Duration::from_secs(10)); + + if let Some(proxy_url) = &settings.proxy_url { + builder = builder.proxy( + reqwest::Proxy::all(proxy_url.as_str()) + .expect("Invalid [proxy] url in configuration"), + ); + } + + let http = builder.build().expect("Failed to build HTTP client"); let req_config = RequestConfig::new().timeout(req_timeout).max_retry_time(req_timeout); From a720b0a3213b0eedf367affdbc5775d34c661d91 Mon Sep 17 00:00:00 2001 From: KaraZajac Date: Mon, 23 Feb 2026 19:17:19 -0500 Subject: [PATCH 2/2] removed OpenSSL dependency and updated styling --- Cargo.lock | 63 ++++++++------------------------------------------- Cargo.toml | 1 + src/config.rs | 8 +------ 3 files changed, 11 insertions(+), 61 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb4f774a..31ebfcad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,7 +180,7 @@ dependencies = [ "objc2-foundation", "parking_lot 0.12.5", "percent-encoding", - "windows-sys 0.60.2", + "windows-sys 0.59.0", "wl-clipboard-rs", "x11rb", ] @@ -1423,7 +1423,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -1539,15 +1539,6 @@ dependencies = [ "phf 0.11.3", ] -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - [[package]] name = "endian-type" version = "0.1.2" @@ -1614,7 +1605,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -2398,11 +2389,9 @@ dependencies = [ "percent-encoding", "pin-project-lite", "socket2 0.6.1", - "system-configuration", "tokio", "tower-service", "tracing", - "windows-registry", ] [[package]] @@ -2806,7 +2795,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi 0.5.2", "libc", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3650,7 +3639,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -3912,7 +3901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.42.0", ] [[package]] @@ -4414,7 +4403,7 @@ dependencies = [ "once_cell", "socket2 0.6.1", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -4710,7 +4699,6 @@ checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64", "bytes", - "encoding_rs", "futures-core", "futures-util", "h2", @@ -4723,7 +4711,6 @@ dependencies = [ "hyper-util", "js-sys", "log", - "mime", "native-tls", "percent-encoding", "pin-project-lite", @@ -5061,7 +5048,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.11.0", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -5587,27 +5574,6 @@ dependencies = [ "syn 2.0.114", ] -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.10.0", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tauri-winrt-notification" version = "0.1.3" @@ -5634,7 +5600,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix 1.1.3", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -6680,17 +6646,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" -[[package]] -name = "windows-registry" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" -dependencies = [ - "windows-link", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - [[package]] name = "windows-result" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 384e1edc..b6da2f4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -96,6 +96,7 @@ features = ["e2e-encryption", "sqlite", "sso-login"] [dependencies.reqwest] version = "0.12" +default-features = false features = ["socks"] [dependencies.tokio] diff --git a/src/config.rs b/src/config.rs index a4f83fe7..0f88324e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -977,13 +977,7 @@ impl ApplicationSettings { let macros = merge_maps(profile.macros.take(), macros).unwrap_or_default(); let layout = profile.layout.take().or(layout).unwrap_or_default(); - - let proxy_url = profile - .proxy - .take() - .unwrap_or_default() - .merge(global_proxy.unwrap_or_default()) - .url; + let proxy_url = profile.proxy.take().unwrap_or_default().merge(global_proxy.unwrap_or_default()).url; let tunables = global.unwrap_or_default(); let tunables = profile.settings.take().unwrap_or_default().merge(tunables);