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
49 changes: 3 additions & 46 deletions src/bub/channels/utils.py
Original file line number Diff line number Diff line change
@@ -1,54 +1,11 @@
"""Utils"""
"""Channel utility helpers."""

from __future__ import annotations

import contextlib
import os
import platform
import subprocess


def _proxy_from_env() -> str | None:
for name in ("HTTPS_PROXY", "https_proxy", "ALL_PROXY", "all_proxy", "HTTP_PROXY", "http_proxy"):
value = os.getenv(name, "").strip()
if value:
return value
return None


def _proxy_from_macos_system() -> str | None:
if platform.system() != "Darwin":
return None
with contextlib.suppress(FileNotFoundError, subprocess.SubprocessError, UnicodeDecodeError):
result = subprocess.run(["scutil", "--proxy"], capture_output=True, text=True, check=False, timeout=2) # noqa: S607
if result.returncode != 0 or not result.stdout:
return None
data: dict[str, str] = {}
for line in result.stdout.splitlines():
if " : " not in line:
continue
key, value = line.split(" : ", 1)
data[key.strip()] = value.strip()
if data.get("HTTPSEnable") == "1":
host = data.get("HTTPSProxy")
port = data.get("HTTPSPort")
if host and port:
return f"http://{host}:{port}"
if data.get("HTTPEnable") == "1":
host = data.get("HTTPProxy")
port = data.get("HTTPPort")
if host and port:
return f"http://{host}:{port}"
return None


def resolve_proxy(explicit_proxy: str | None) -> tuple[str | None, str]:
if explicit_proxy:
return explicit_proxy, "explicit"
env_proxy = _proxy_from_env()
if env_proxy:
return env_proxy, "env"
system_proxy = _proxy_from_macos_system()
if system_proxy:
return system_proxy, "system"

# Proxy usage must be opt-in; ignore ambient env vars and OS proxy settings.
return None, "none"
22 changes: 5 additions & 17 deletions tests/test_channels_proxy.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,16 @@
from __future__ import annotations

from bub.channels.utils import _proxy_from_macos_system, resolve_proxy
from bub.channels.utils import resolve_proxy


def test_resolve_proxy_prefers_explicit_over_env(monkeypatch) -> None:
def test_resolve_proxy_prefers_explicit_over_ambient(monkeypatch) -> None:
monkeypatch.setenv("HTTPS_PROXY", "http://env.proxy:8080")
proxy, source = resolve_proxy("http://explicit.proxy:9000")
assert proxy == "http://explicit.proxy:9000"
assert source == "explicit"


def test_resolve_proxy_uses_env_when_present(monkeypatch) -> None:
monkeypatch.setenv("HTTPS_PROXY", "http://env.proxy:8080")
def test_resolve_proxy_is_opt_in(monkeypatch) -> None:
proxy, source = resolve_proxy(None)
assert proxy == "http://env.proxy:8080"
assert source == "env"


def test_proxy_from_macos_system_parses_https(monkeypatch) -> None:
monkeypatch.setattr("bub.channels.utils.platform.system", lambda: "Darwin")

class _Result:
returncode = 0
stdout = "HTTPSEnable : 1\nHTTPSProxy : 127.0.0.1\nHTTPSPort : 7890\n"

monkeypatch.setattr("bub.channels.utils.subprocess.run", lambda *_, **__: _Result())
assert _proxy_from_macos_system() == "http://127.0.0.1:7890"
assert proxy is None
assert source == "none"
Loading