Skip to content

Add SOCKS5 and HTTP proxy support with direct-connection fallback - #50

Merged
iebb merged 3 commits into
iebb:mainfrom
4fuu:feat/proxy
Sep 24, 2026
Merged

iebb merged 3 commits into
iebb:mainfrom
4fuu:feat/proxy

Conversation

@4fuu

@4fuu 4fuu commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Termgram could only connect directly, so users behind restrictive networks had no way to reach Telegram. The underlying grammers-mtsender supports SOCKS5 behind its proxy feature, but Termgram did not enable it and had no UI or configuration for it.

Solution

Enable mtsender's proxy feature and extend the vendored patch:

  • ConnectionParams::proxy_fallback (vendored addition): the configured proxy is tried first with a ten-second timeout, then the same datacenter address directly. Only I/O errors or that timeout fall back; a proxy that answers but breaks the protocol does not mask the failure. Without the flag, a configured proxy is used exclusively.
  • The vendored crate additionally accepts http:// proxy URLs and negotiates a plain HTTP CONNECT tunnel (optional Proxy-Authorization: Basic, response status validated, no new dependencies). Other schemes stay rejected. Reapply notes are in vendor/README.md.

Application side:

  • TERMGRAM_PROXY (socks5://host:port or http://host:port) overrides the saved preference and is strict: connections never bypass it with a direct fallback, and an invalid value disables proxying for the run with a startup warning.
  • The proxy editor (press p on the sign-in, connecting, or fatal screen) validates a URL, saves it to settings.conf and restarts the Telegram worker through the existing account-switch path. An empty value connects directly.
  • A saved proxy is preferred for every connection and falls back to direct connections when unreachable.
  • Proxy credentials are redacted in Debug output.

Notes for the maintainer

  • The proxy_fallback option and the HTTP CONNECT support live in the vendored grammers-mtsender patch per the existing vendor/ convention; both would be welcome upstream and the patch is small enough to rebase away once available.

Validation

  • cargo fmt --all -- --check, cargo clippy --locked --all-targets --all-features -- -D warnings, cargo test --locked --all-targets --all-features (275 tests) and the vendored mtsender --lib tests pass.
  • New tests cover proxy URL validation, env-over-settings precedence (strict, no fallback), settings round-trip with proxy=, credential redaction in Debug, the editor save/clear/invalid-input flows, the vendored fallback attempt list, the CONNECT response parser, header framing and the base64 encoder.
  • Verified end to end: a saved proxy pointing at a dead address times out after ten seconds and falls back to a direct connection; a strict TERMGRAM_PROXY against a dead address fails without fallback; and a local HTTP CONNECT proxy (with and without credentials) carried the connection to the sign-in screen.

4fuu and others added 3 commits September 22, 2026 07:26
Termgram could only connect directly, so users behind restrictive
networks had no way to reach Telegram.

Enable grammers-mtsender's proxy feature and extend the vendored
connection setup: ConnectionParams::proxy_fallback tries the configured
SOCKS5 proxy first with a ten-second timeout and then the same
datacenter address directly, falling back only on I/O errors or that
timeout.

resolve_proxy prefers TERMGRAM_PROXY over the saved preference. The
environment value is strict and never falls back; an invalid value
disables proxying with a startup warning. The saved preference prefers
the proxy but falls back to direct connections when it is unreachable.

Pressing p on the sign-in, connecting or fatal screen opens a proxy
editor that validates and saves a socks5://host:port URL to
settings.conf and restarts the Telegram worker through the existing
account-switch path. Pre-connection screens now use the Input keymap
context so the shortcut and editor editing work there.

Validation: cargo fmt, clippy (-D warnings) and the full test suite
pass, including the vendored mtsender unit test; the fallback and the
strict environment behavior were verified against a live connection.

Amp-Thread-ID: https://ampcode.com/threads/T-01a0c24b-d4c2-707c-86c1-da9f060dd6b7
Co-authored-by: Amp <amp@ampcode.com>
The proxy setting only accepted SOCKS5, but common corporate and
personal proxies speak HTTP CONNECT.

The vendored mtsender patch negotiates an HTTP CONNECT tunnel for
http:// proxy URLs: it resolves the proxy host, sends CONNECT with the
optional Proxy-Authorization: Basic header (small local base64 encoder,
no new dependency), validates the response status line and keeps the
tunnel as a raw stream. Schemes other than socks5 and http are still
rejected. Proxy fallback and timeout behavior are unchanged and apply
to both schemes.

Termgram's validate_proxy and the proxy editor accept both schemes now.

Validation: cargo fmt, clippy (-D warnings) and the full test suite
pass, including new vendored tests for the response parser, header
framing and base64 encoding. Verified end to end through a local HTTP
CONNECT proxy with and without credentials: the tunnel carried the
Telegram connection to the sign-in screen.

Amp-Thread-ID: https://ampcode.com/threads/T-01a0c24b-d4c2-707c-86c1-da9f060dd6b7
Co-authored-by: Amp <amp@ampcode.com>
The proxy timeout and fallback logic in establish_stream referenced
ServerAddr::Proxied and PROXY_CONNECT_TIMEOUT without a feature gate,
so building grammers-mtsender without its proxy feature (as the CI
update-payload test does) failed to compile. Gate those references and
move the proxy-only test import into the test to avoid an unused-import
warning without the feature.

Amp-Thread-ID: https://ampcode.com/threads/T-01a0c24b-d4c2-707c-86c1-da9f060dd6b7
Co-authored-by: Amp <amp@ampcode.com>
@4fuu

4fuu commented Sep 23, 2026

Copy link
Copy Markdown
Contributor Author

@iebb

@iebb
iebb merged commit 616f8a7 into iebb:main Sep 24, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants