From e962326f934f702903f95f5564582a830a9756ab Mon Sep 17 00:00:00 2001 From: hsd221 Date: Sun, 3 May 2026 14:36:45 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=94=AF=E6=8C=81=20HTTP=20=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE=E5=92=8C=E5=86=85=E7=BD=91=E5=9C=B0=E5=9D=80=E8=AE=BF?= =?UTF-8?q?=E9=97=AE=EF=BC=8C=E4=BF=AE=E5=A4=8D=E8=81=8A=E5=A4=A9=20URL=20?= =?UTF-8?q?=E7=BC=BA=E5=8D=8F=E8=AE=AE=E5=89=8D=E7=BC=80=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - validate_public_url 默认允许 http 和 https 协议 - 移除 _is_forbidden_ip_address 中 is_private 和 is_site_local 拦截,允许内网 IP - validate_public_url 中无 scheme 时自动补全 http:// - normalize_openai_base_url 中无协议前缀时自动补全 http:// - pyproject.toml 添加 httpx[socks] 依赖以支持 SOCKS 代理 --- pyproject.toml | 2 +- src/llm_models/openai_compat.py | 7 ++++++- src/webui/utils/network_security.py | 6 +++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9f8c5a28..d80d10c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ dependencies = [ "faiss-cpu>=1.11.0", "fastapi>=0.116.0", "google-genai>=1.39.1", - "httpx", + "httpx[socks]", "jieba>=0.42.1", "json-repair>=0.47.6", "maim-message>=0.6.2", diff --git a/src/llm_models/openai_compat.py b/src/llm_models/openai_compat.py index 19190e0a..94f26a5c 100644 --- a/src/llm_models/openai_compat.py +++ b/src/llm_models/openai_compat.py @@ -26,12 +26,17 @@ class OpenAICompatibleRequestOverrides: def normalize_openai_base_url(base_url: str) -> str: """规范化 OpenAI 兼容接口的基础地址。 + 去掉尾部斜杠,且如果缺少协议前缀则自动补全 http://。 + Args: base_url: 原始基础地址。 Returns: - str: 去掉尾部斜杠后的地址。 + str: 规范化后的地址。 """ + base_url = base_url.strip() + if base_url and "://" not in base_url: + base_url = "http://" + base_url return base_url.rstrip("/") diff --git a/src/webui/utils/network_security.py b/src/webui/utils/network_security.py index f8cd580f..9d1577d1 100644 --- a/src/webui/utils/network_security.py +++ b/src/webui/utils/network_security.py @@ -31,19 +31,19 @@ def _is_forbidden_ip_address(address: ipaddress.IPv4Address | ipaddress.IPv6Addr address.is_loopback, address.is_link_local, address.is_multicast, - address.is_private, address.is_reserved, address.is_unspecified, - getattr(address, "is_site_local", False), ) ) -def validate_public_url(url: str, allowed_schemes: Iterable[str] = ("https",)) -> str: +def validate_public_url(url: str, allowed_schemes: Iterable[str] = ("http", "https")) -> str: normalized_url = url.strip() if not normalized_url: raise ValueError("URL 不能为空") + if "://" not in normalized_url: + normalized_url = "http://" + normalized_url parsed = urlparse(normalized_url) allowed_scheme_set = {scheme.lower() for scheme in allowed_schemes} if parsed.scheme.lower() not in allowed_scheme_set: