mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-22 00:31:44 +00:00
fix(sync-httpx): respect proxy env vars when force_ipv4 is enabled
When `force_ipv4: true` is set in config, the sync HTTPHandler creates a custom `HTTPTransport(local_address="0.0.0.0")` which causes httpx to ignore `HTTP_PROXY`/`HTTPS_PROXY` environment variables. This breaks providers that use the sync client path (e.g. ChatGPT authenticator) when running behind a proxy. The fix detects proxy env vars at client creation time and skips the custom transport so httpx auto-detects proxy settings. When no proxy is configured, the IPv4-forcing transport is used as before. Closes #24562 See also #24983
This commit is contained in:
parent
c011a7e3ba
commit
81e79f62c6
2 changed files with 71 additions and 0 deletions
|
|
@ -1047,6 +1047,19 @@ class HTTPHandler:
|
|||
if client is None:
|
||||
transport = self._create_sync_transport()
|
||||
|
||||
# When proxy is configured via env vars, skip custom transport.
|
||||
# httpx ignores proxy env vars when an explicit transport is
|
||||
# provided, which breaks providers that use the sync client
|
||||
# (e.g. ChatGPT authenticator) behind a proxy.
|
||||
proxy_url = (
|
||||
os.environ.get("HTTPS_PROXY")
|
||||
or os.environ.get("https_proxy")
|
||||
or os.environ.get("HTTP_PROXY")
|
||||
or os.environ.get("http_proxy")
|
||||
)
|
||||
if proxy_url and transport is not None:
|
||||
transport = None
|
||||
|
||||
# Create a client with a connection pool
|
||||
self.client = httpx.Client(
|
||||
transport=transport,
|
||||
|
|
|
|||
|
|
@ -675,6 +675,64 @@ async def test_httpx_handler_uses_env_user_agent(monkeypatch):
|
|||
await handler.close()
|
||||
|
||||
|
||||
def test_sync_http_handler_skips_custom_transport_when_proxy_set(monkeypatch):
|
||||
"""
|
||||
When HTTPS_PROXY is set and force_ipv4 creates a custom transport,
|
||||
the sync HTTPHandler must skip the custom transport so that httpx
|
||||
auto-detects proxy from environment variables.
|
||||
|
||||
httpx ignores proxy env vars when an explicit transport is provided,
|
||||
which breaks sync-path providers (e.g. ChatGPT authenticator) behind
|
||||
a proxy. See GitHub issue #24562.
|
||||
"""
|
||||
original_force_ipv4 = litellm.force_ipv4
|
||||
litellm.force_ipv4 = True
|
||||
|
||||
try:
|
||||
# With proxy: custom transport should be dropped
|
||||
monkeypatch.setenv("HTTPS_PROXY", "http://proxy:8080")
|
||||
handler = HTTPHandler()
|
||||
try:
|
||||
transport = handler.client._transport
|
||||
assert not isinstance(transport, httpx.HTTPTransport)
|
||||
finally:
|
||||
handler.close()
|
||||
|
||||
# Without proxy: custom transport should be applied (force_ipv4)
|
||||
monkeypatch.delenv("HTTPS_PROXY", raising=False)
|
||||
monkeypatch.delenv("HTTP_PROXY", raising=False)
|
||||
handler2 = HTTPHandler()
|
||||
try:
|
||||
transport2 = handler2.client._transport
|
||||
assert isinstance(transport2, httpx.HTTPTransport)
|
||||
finally:
|
||||
handler2.close()
|
||||
finally:
|
||||
litellm.force_ipv4 = original_force_ipv4
|
||||
|
||||
|
||||
def test_sync_http_handler_prefers_https_proxy_over_http_proxy(monkeypatch):
|
||||
"""
|
||||
HTTPS_PROXY takes precedence over HTTP_PROXY, matching httpx convention.
|
||||
"""
|
||||
original_force_ipv4 = litellm.force_ipv4
|
||||
litellm.force_ipv4 = True
|
||||
|
||||
try:
|
||||
monkeypatch.setenv("HTTPS_PROXY", "http://https-proxy:8080")
|
||||
monkeypatch.setenv("HTTP_PROXY", "http://http-proxy:8080")
|
||||
|
||||
handler = HTTPHandler()
|
||||
try:
|
||||
# Should not have custom transport (proxy takes priority)
|
||||
transport = handler.client._transport
|
||||
assert not isinstance(transport, httpx.HTTPTransport)
|
||||
finally:
|
||||
handler.close()
|
||||
finally:
|
||||
litellm.force_ipv4 = original_force_ipv4
|
||||
|
||||
|
||||
def test_get_httpx_client_applies_float_timeout_without_mocking_handler():
|
||||
"""
|
||||
Exercise real _get_httpx_client + HTTPHandler: params={'timeout': x} must reach httpx.Client(timeout=...).
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue