From 30769545cdbf558d6bd88bf44f15f2434cc54d78 Mon Sep 17 00:00:00 2001 From: dmx <1051584731@qq.com> Date: Mon, 22 Dec 2025 01:24:50 +0800 Subject: [PATCH] Fix proxy normalization and pool handling --- app/core/config.py | 14 ++++++++++++-- app/core/proxy_pool.py | 33 ++++++++++++++++++++++++++++++--- app/services/grok/cache.py | 2 +- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index dc68617..7355dc5 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -65,8 +65,16 @@ class ConfigManager: toml.dump(default, f) def _normalize_proxy(self, proxy: str) -> str: - """标准化代理URL(socks5:// → socks5h://)""" - if proxy and proxy.startswith("socks5://"): + """标准化代理URL(sock5/socks5 → socks5h://)""" + if not proxy: + return proxy + + proxy = proxy.strip() + if proxy.startswith("sock5h://"): + proxy = proxy.replace("sock5h://", "socks5h://", 1) + if proxy.startswith("sock5://"): + proxy = proxy.replace("sock5://", "socks5://", 1) + if proxy.startswith("socks5://"): return proxy.replace("socks5://", "socks5h://", 1) return proxy @@ -90,6 +98,8 @@ class ConfigManager: if section == "grok": if "proxy_url" in config: config["proxy_url"] = self._normalize_proxy(config["proxy_url"]) + if "cache_proxy_url" in config: + config["cache_proxy_url"] = self._normalize_proxy(config["cache_proxy_url"]) if "cf_clearance" in config: config["cf_clearance"] = self._normalize_cf(config["cf_clearance"]) diff --git a/app/core/proxy_pool.py b/app/core/proxy_pool.py index eaea5f5..acc2059 100644 --- a/app/core/proxy_pool.py +++ b/app/core/proxy_pool.py @@ -27,8 +27,17 @@ class ProxyPool: proxy_pool_url: 代理池API URL,返回单个代理地址 proxy_pool_interval: 代理池刷新间隔(秒) """ - self._static_proxy = proxy_url if proxy_url else None - self._pool_url = proxy_pool_url if proxy_pool_url else None + self._static_proxy = self._normalize_proxy(proxy_url) if proxy_url else None + pool_url = proxy_pool_url.strip() if proxy_pool_url else None + if pool_url and self._looks_like_proxy_url(pool_url): + normalized_proxy = self._normalize_proxy(pool_url) + if not self._static_proxy: + self._static_proxy = normalized_proxy + logger.warning("[ProxyPool] proxy_pool_url看起来是代理地址,已作为静态代理使用,请改用proxy_url") + else: + logger.warning("[ProxyPool] proxy_pool_url看起来是代理地址,已忽略(使用proxy_url)") + pool_url = None + self._pool_url = pool_url self._fetch_interval = proxy_pool_interval self._enabled = bool(self._pool_url) @@ -84,7 +93,7 @@ class ProxyPool: async with session.get(self._pool_url) as response: if response.status == 200: proxy_text = await response.text() - proxy = proxy_text.strip() + proxy = self._normalize_proxy(proxy_text.strip()) # 验证代理格式 if self._validate_proxy(proxy): @@ -129,6 +138,24 @@ class ProxyPool: valid_protocols = ['http://', 'https://', 'socks5://', 'socks5h://'] return any(proxy.startswith(proto) for proto in valid_protocols) + + def _normalize_proxy(self, proxy: str) -> str: + """标准化代理URL(sock5/socks5 → socks5h://)""" + if not proxy: + return proxy + + proxy = proxy.strip() + if proxy.startswith("sock5h://"): + proxy = proxy.replace("sock5h://", "socks5h://", 1) + if proxy.startswith("sock5://"): + proxy = proxy.replace("sock5://", "socks5://", 1) + if proxy.startswith("socks5://"): + return proxy.replace("socks5://", "socks5h://", 1) + return proxy + + def _looks_like_proxy_url(self, url: str) -> bool: + """判断URL是否像代理地址(避免误把代理池API当代理)""" + return url.startswith(("sock5://", "sock5h://", "socks5://", "socks5h://")) def get_current_proxy(self) -> Optional[str]: """获取当前使用的代理(同步方法) diff --git a/app/services/grok/cache.py b/app/services/grok/cache.py index 95e86b1..21388dd 100644 --- a/app/services/grok/cache.py +++ b/app/services/grok/cache.py @@ -71,7 +71,7 @@ class CacheService: retry_403_count = 0 while retry_403_count <= max_403_retries: - proxy = setting.get_proxy("cache") + proxy = await setting.get_proxy_async("cache") proxies = {"http": proxy, "https": proxy} if proxy else {} if proxy and outer_retry == 0 and retry_403_count == 0: