From cab4a5fddeeae20696c87cbd767a77944cc0eafd Mon Sep 17 00:00:00 2001 From: deexsed Date: Thu, 30 Apr 2026 09:52:14 +0300 Subject: [PATCH 1/2] =?UTF-8?q?fix(config):=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=B2=D0=B0=D0=BB=D0=B8=D0=B4?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B8=20=D0=BD=D0=B0=D0=B4=D0=B5?= =?UTF-8?q?=D0=B6=D0=BD=D1=8B=D0=B9=20fallback=20=D0=B4=D0=BB=D1=8F=20CF?= =?UTF-8?q?=20domain=20list?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `proxy/config.py` зависел от внешнего списка доменов (GitHub raw): при длительных сбоях или “мусорном” ответе источник мог ухудшать качество пула. --- proxy/config.py | 68 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/proxy/config.py b/proxy/config.py index 9c630b90..bf89c636 100644 --- a/proxy/config.py +++ b/proxy/config.py @@ -34,6 +34,8 @@ def _dd(s: str) -> str: CFPROXY_DEFAULT_DOMAINS: List[str] = [_dd(d) for d in _CFPROXY_ENC] +_CFPROXY_MIN_VALID_DOMAINS = 3 +_cfproxy_last_good_domains: List[str] = list(CFPROXY_DEFAULT_DOMAINS) @dataclass @@ -70,28 +72,82 @@ def _fetch_cfproxy_domain_list() -> List[str]: return [] +def _is_valid_domain(domain: str) -> bool: + if not domain or len(domain) > 253: + return False + if domain.startswith('.') or domain.endswith('.'): + return False + labels = domain.split('.') + if len(labels) < 2: + return False + for label in labels: + if not label or len(label) > 63: + return False + if label[0] == '-' or label[-1] == '-': + return False + if not all(ch.isalnum() or ch == '-' for ch in label): + return False + # TLD should contain letters and be at least 2 chars. + tld = labels[-1] + if len(tld) < 2 or not any(ch.isalpha() for ch in tld): + return False + return True + + +def _normalize_domain_pool(domains: List[str]) -> List[str]: + seen = set() + normalized: List[str] = [] + for domain in domains: + item = domain.strip().lower() + if not _is_valid_domain(item): + continue + if item in seen: + continue + seen.add(item) + normalized.append(item) + return normalized + + def refresh_cfproxy_domains() -> None: + global _cfproxy_last_good_domains + if proxy_config.cfproxy_user_domain: return - - fetched = _fetch_cfproxy_domain_list() - if fetched: - seen = set() - pool = [d for d in fetched if not (d in seen or seen.add(d))] + fetched = _fetch_cfproxy_domain_list() + pool = _normalize_domain_pool(fetched) + if len(pool) >= _CFPROXY_MIN_VALID_DOMAINS: + _cfproxy_last_good_domains = pool balancer.update_domains_list(pool) log.info("CF proxy domain pool updated from GitHub (%d domains)", len(pool)) + return + + fallback_pool = _cfproxy_last_good_domains or CFPROXY_DEFAULT_DOMAINS + balancer.update_domains_list(fallback_pool) + if fetched: + log.warning( + "Ignoring fetched CF proxy domains due to low-quality payload " + "(total=%d, valid=%d, required>=%d); using fallback pool (%d domains)", + len(fetched), len(pool), _CFPROXY_MIN_VALID_DOMAINS, len(fallback_pool), + ) + else: + log.warning( + "CF proxy domain refresh failed or empty response; " + "using fallback pool (%d domains)", + len(fallback_pool), + ) _refresh_stop: threading.Event = threading.Event() def start_cfproxy_domain_refresh() -> None: - global _refresh_stop + global _refresh_stop, _cfproxy_last_good_domains _refresh_stop.set() _refresh_stop = threading.Event() stop = _refresh_stop + _cfproxy_last_good_domains = list(CFPROXY_DEFAULT_DOMAINS) balancer.update_domains_list(CFPROXY_DEFAULT_DOMAINS) def _loop(): From 8c5584824bea43e820a36194b5913fd4755606bd Mon Sep 17 00:00:00 2001 From: deexsed Date: Thu, 30 Apr 2026 13:32:38 +0300 Subject: [PATCH 2/2] remove _cfproxy_last_good_domains --- proxy/config.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/proxy/config.py b/proxy/config.py index bf89c636..ee4b6b30 100644 --- a/proxy/config.py +++ b/proxy/config.py @@ -35,7 +35,6 @@ def _dd(s: str) -> str: CFPROXY_DEFAULT_DOMAINS: List[str] = [_dd(d) for d in _CFPROXY_ENC] _CFPROXY_MIN_VALID_DOMAINS = 3 -_cfproxy_last_good_domains: List[str] = list(CFPROXY_DEFAULT_DOMAINS) @dataclass @@ -109,32 +108,26 @@ def _normalize_domain_pool(domains: List[str]) -> List[str]: def refresh_cfproxy_domains() -> None: - global _cfproxy_last_good_domains - if proxy_config.cfproxy_user_domain: return fetched = _fetch_cfproxy_domain_list() pool = _normalize_domain_pool(fetched) if len(pool) >= _CFPROXY_MIN_VALID_DOMAINS: - _cfproxy_last_good_domains = pool balancer.update_domains_list(pool) log.info("CF proxy domain pool updated from GitHub (%d domains)", len(pool)) return - fallback_pool = _cfproxy_last_good_domains or CFPROXY_DEFAULT_DOMAINS - balancer.update_domains_list(fallback_pool) if fetched: log.warning( "Ignoring fetched CF proxy domains due to low-quality payload " - "(total=%d, valid=%d, required>=%d); using fallback pool (%d domains)", - len(fetched), len(pool), _CFPROXY_MIN_VALID_DOMAINS, len(fallback_pool), + "(total=%d, valid=%d, required>=%d); keeping current domain pool", + len(fetched), len(pool), _CFPROXY_MIN_VALID_DOMAINS, ) else: log.warning( "CF proxy domain refresh failed or empty response; " - "using fallback pool (%d domains)", - len(fallback_pool), + "keeping current domain pool", ) @@ -142,12 +135,11 @@ def refresh_cfproxy_domains() -> None: def start_cfproxy_domain_refresh() -> None: - global _refresh_stop, _cfproxy_last_good_domains + global _refresh_stop _refresh_stop.set() _refresh_stop = threading.Event() stop = _refresh_stop - _cfproxy_last_good_domains = list(CFPROXY_DEFAULT_DOMAINS) balancer.update_domains_list(CFPROXY_DEFAULT_DOMAINS) def _loop():