From d7c41f3cef592346ecea47b11c83a966c0248e72 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Sat, 28 Mar 2026 14:23:27 -0700 Subject: [PATCH] fix(telegram): honor proxy env vars in fallback transport (salvage #3411) (#3591) * fix: keep gateway running through telegram proxy failures - continue gateway startup in degraded mode when Telegram cannot connect yet - ensure Telegram fallback transport also honors proxy env vars - support reconnect retries without taking down the whole gateway * test(telegram): cover proxy env handling in fallback transport --------- Co-authored-by: kufufu9 --- gateway/platforms/telegram_network.py | 12 ++++++++++++ tests/gateway/test_telegram_network.py | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/gateway/platforms/telegram_network.py b/gateway/platforms/telegram_network.py index 719236947..93f1f0fb5 100644 --- a/gateway/platforms/telegram_network.py +++ b/gateway/platforms/telegram_network.py @@ -12,6 +12,7 @@ from __future__ import annotations import asyncio import ipaddress import logging +import os import socket from typing import Iterable, Optional @@ -43,6 +44,14 @@ _DOH_PROVIDERS: list[dict] = [ _SEED_FALLBACK_IPS: list[str] = ["149.154.167.220"] +def _resolve_proxy_url() -> str | None: + for key in ("HTTPS_PROXY", "HTTP_PROXY", "ALL_PROXY", "https_proxy", "http_proxy", "all_proxy"): + value = (os.environ.get(key) or "").strip() + if value: + return value + return None + + class TelegramFallbackTransport(httpx.AsyncBaseTransport): """Retry Telegram Bot API requests via fallback IPs while preserving TLS/SNI. @@ -54,6 +63,9 @@ class TelegramFallbackTransport(httpx.AsyncBaseTransport): def __init__(self, fallback_ips: Iterable[str], **transport_kwargs): self._fallback_ips = [ip for ip in dict.fromkeys(_normalize_fallback_ips(fallback_ips))] + proxy_url = _resolve_proxy_url() + if proxy_url and "proxy" not in transport_kwargs: + transport_kwargs["proxy"] = proxy_url self._primary = httpx.AsyncHTTPTransport(**transport_kwargs) self._fallbacks = { ip: httpx.AsyncHTTPTransport(**transport_kwargs) for ip in self._fallback_ips diff --git a/tests/gateway/test_telegram_network.py b/tests/gateway/test_telegram_network.py index 7591ae85f..2770211f3 100644 --- a/tests/gateway/test_telegram_network.py +++ b/tests/gateway/test_telegram_network.py @@ -315,6 +315,24 @@ class TestFallbackTransportInit: transport = tnet.TelegramFallbackTransport(["149.154.167.220", "not-an-ip"]) assert transport._fallback_ips == ["149.154.167.220"] + def test_uses_proxy_env_for_primary_and_fallback_transports(self, monkeypatch): + seen_kwargs = [] + + def factory(**kwargs): + seen_kwargs.append(kwargs.copy()) + return FakeTransport([], {}) + + for key in ("HTTPS_PROXY", "HTTP_PROXY", "ALL_PROXY", "https_proxy", "http_proxy", "all_proxy"): + monkeypatch.delenv(key, raising=False) + monkeypatch.setenv("HTTPS_PROXY", "http://proxy.example:8080") + monkeypatch.setattr(tnet.httpx, "AsyncHTTPTransport", factory) + + transport = tnet.TelegramFallbackTransport(["149.154.167.220"]) + + assert transport._fallback_ips == ["149.154.167.220"] + assert len(seen_kwargs) == 2 + assert all(kwargs["proxy"] == "http://proxy.example:8080" for kwargs in seen_kwargs) + class TestFallbackTransportClose: @pytest.mark.asyncio