Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ version = "0.14.0"
default-features = false
features = ["e2e-encryption", "sqlite", "sso-login"]

[dependencies.reqwest]
version = "0.12"
default-features = false
features = ["socks"]

[dependencies.tokio]
version = "1.24.1"
features = ["macros", "net", "rt-multi-thread", "sync", "time"]
Expand Down
5 changes: 5 additions & 0 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ split = [
[macros."normal|visual"]
"V" = "<C-W>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/"
Expand Down
27 changes: 27 additions & 0 deletions docs/iamb.5
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
21 changes: 21 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,20 @@ pub enum WindowLayout {
Split { split: Vec<WindowLayout> },
}

#[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<String>,
}

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 {
Expand All @@ -831,6 +845,7 @@ pub struct ProfileConfig {
pub dirs: Option<Directories>,
pub layout: Option<Layout>,
pub macros: Option<Macros>,
pub proxy: Option<ProxyConfig>,
}

#[derive(Clone, Deserialize)]
Expand All @@ -841,6 +856,7 @@ pub struct IambConfig {
pub dirs: Option<Directories>,
pub layout: Option<Layout>,
pub macros: Option<Macros>,
pub proxy: Option<ProxyConfig>,
}

impl IambConfig {
Expand Down Expand Up @@ -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<String>,
}

impl ApplicationSettings {
Expand Down Expand Up @@ -915,6 +933,7 @@ impl ApplicationSettings {
settings: global,
layout,
macros,
proxy: global_proxy,
} = config;

validate_profile_names(&profiles);
Expand Down Expand Up @@ -958,6 +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 tunables = global.unwrap_or_default();
let tunables = profile.settings.take().unwrap_or_default().merge(tunables);
Expand Down Expand Up @@ -1011,6 +1031,7 @@ impl ApplicationSettings {
dirs,
layout,
macros,
proxy_url,
};

Ok(settings)
Expand Down
2 changes: 2 additions & 0 deletions src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}

Expand Down
15 changes: 11 additions & 4 deletions src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down