From 1e0e1fdfc26c857a53f8f6030288b152e41d4df0 Mon Sep 17 00:00:00 2001 From: snomiao Date: Wed, 29 Apr 2026 09:00:49 +0900 Subject: [PATCH] feat: add HTTP/HTTPS proxy configuration via CLI args and settings file - New CLI args: --http-proxy, --https-proxy, --no-proxy - Falls back to comfy.settings.json keys: Comfy.Network.Proxy.HttpUrl, Comfy.Network.Proxy.HttpsUrl, Comfy.Network.Proxy.NoProxy - Priority: CLI args override all; settings file fills gaps only (existing env vars take precedence over settings file) - Credentials are redacted in startup logs via netloc-split approach (safe against malformed ports and empty-username/non-empty-password) - Specific exception handling (OSError, JSONDecodeError) with warning log --- comfy/cli_args.py | 7 +++++ main.py | 78 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 83 insertions(+), 2 deletions(-) diff --git a/comfy/cli_args.py b/comfy/cli_args.py index dbaadf723..453aedc8c 100644 --- a/comfy/cli_args.py +++ b/comfy/cli_args.py @@ -233,6 +233,13 @@ parser.add_argument( help="Set the base URL for the ComfyUI API. (default: https://api.comfy.org)", ) +parser.add_argument("--http-proxy", type=str, default=None, metavar="URL", + help="HTTP/HTTPS proxy URL (e.g. http://127.0.0.1:7890). Sets HTTP_PROXY and HTTPS_PROXY environment variables so all outbound traffic is routed through the proxy.") +parser.add_argument("--https-proxy", type=str, default=None, metavar="URL", + help="HTTPS proxy URL. If not set, --http-proxy is used for both HTTP and HTTPS traffic.") +parser.add_argument("--no-proxy", type=str, default=None, metavar="HOSTS", + help="Comma-separated list of hosts that should bypass the proxy (e.g. localhost,127.0.0.1,*.local).") + database_default_path = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", "user", "comfyui.db") ) diff --git a/main.py b/main.py index dbaf2745c..b34f40cda 100644 --- a/main.py +++ b/main.py @@ -2,6 +2,8 @@ import comfy.options comfy.options.enable_args_parsing() import os +import logging +import sys import importlib.util import shutil import importlib.metadata @@ -9,6 +11,74 @@ import folder_paths import time from comfy.cli_args import args, enables_dynamic_vram from app.logger import setup_logger + + +def _redact_proxy_url(url: str) -> str: + """Return url with userinfo replaced by *** to prevent credential leaks in logs.""" + from urllib.parse import urlsplit, urlunsplit + try: + parts = urlsplit(url) + if '@' in (parts.netloc or ''): + _, hostinfo = parts.netloc.rsplit('@', 1) + return urlunsplit(parts._replace(netloc=f"***:***@{hostinfo}")) + except Exception: + return '***' + return url + + +def _apply_proxy_env_vars() -> None: + """Apply proxy environment variables. + + Priority: CLI args override everything. Settings file fills in only when + neither a CLI arg nor an existing environment variable is present. + """ + import json as _json + + http_proxy_cli = args.http_proxy + https_proxy_cli = args.https_proxy + no_proxy_cli = args.no_proxy + + settings_http = settings_https = settings_no_proxy = "" + user_dir = args.user_directory or os.path.join( + args.base_directory or os.path.dirname(os.path.realpath(__file__)), "user" + ) + settings_path = os.path.join(user_dir, "default", "comfy.settings.json") + if os.path.isfile(settings_path): + try: + with open(settings_path) as f: + cfg = _json.load(f) + settings_http = cfg.get("Comfy.Network.Proxy.HttpUrl") or "" + settings_https = cfg.get("Comfy.Network.Proxy.HttpsUrl") or "" + settings_no_proxy = cfg.get("Comfy.Network.Proxy.NoProxy") or "" + except (OSError, _json.JSONDecodeError) as exc: + logging.warning("Could not load proxy settings from %s: %s", settings_path, exc) + + def _force(upper: str, lower: str, value: str) -> None: + os.environ[upper] = value + os.environ[lower] = value + + def _fill(upper: str, lower: str, value: str) -> None: + if value and not os.environ.get(upper): + os.environ[upper] = value + os.environ[lower] = value + + # CLI args take precedence over all existing environment variables + if http_proxy_cli: + _force('HTTP_PROXY', 'http_proxy', http_proxy_cli) + if not https_proxy_cli: + _force('HTTPS_PROXY', 'https_proxy', http_proxy_cli) + if https_proxy_cli: + _force('HTTPS_PROXY', 'https_proxy', https_proxy_cli) + if no_proxy_cli: + _force('NO_PROXY', 'no_proxy', no_proxy_cli) + + # Settings file values only fill gaps (existing env vars take precedence) + _fill('HTTP_PROXY', 'http_proxy', settings_http) + if not os.environ.get('HTTPS_PROXY'): + _fill('HTTPS_PROXY', 'https_proxy', settings_https or settings_http) + _fill('NO_PROXY', 'no_proxy', settings_no_proxy) + + setup_logger(log_level=args.verbose, use_stdout=args.log_stdout) from app.assets.seeder import asset_seeder @@ -17,8 +87,6 @@ import itertools import utils.extra_config from utils.mime_types import init_mime_types import faulthandler -import logging -import sys from comfy_execution.progress import get_progress_state from comfy_execution.utils import get_executing_context from comfy_api import feature_flags @@ -28,6 +96,12 @@ if __name__ == "__main__": #NOTE: These do not do anything on core ComfyUI, they are for custom nodes. os.environ['HF_HUB_DISABLE_TELEMETRY'] = '1' os.environ['DO_NOT_TRACK'] = '1' + _apply_proxy_env_vars() + +if os.environ.get('HTTP_PROXY'): + logging.info("HTTP proxy configured: %s", _redact_proxy_url(os.environ['HTTP_PROXY'])) +if os.environ.get('HTTPS_PROXY'): + logging.info("HTTPS proxy configured: %s", _redact_proxy_url(os.environ['HTTPS_PROXY'])) faulthandler.enable(file=sys.stderr, all_threads=False)