from __future__ import annotations from dataclasses import dataclass from typing import Iterable import httpx # High-traffic destinations that often reveal proxy bans quickly. POPULAR_SITES: tuple[tuple[str, str], ...] = ( ("Google", "https://www.google.com/generate_204"), ("YouTube", "https://www.youtube.com/"), ("Facebook", "https://www.facebook.com/"), ("Instagram", "https://www.instagram.com/"), ("X", "https://x.com/"), ("Reddit", "https://www.reddit.com/"), ("Wikipedia", "https://www.wikipedia.org/"), ("Amazon", "https://www.amazon.com/"), ("Netflix", "https://www.netflix.com/"), ("GitHub", "https://github.com/"), ("Cloudflare", "https://www.cloudflare.com/"), ("Microsoft", "https://www.microsoft.com/"), ("TikTok", "https://www.tiktok.com/"), ("BBC", "https://www.bbc.com/"), ("DuckDuckGo", "https://duckduckgo.com/"), ) _BANNED_STATUS_CODES = {401, 403, 407, 418, 429, 451} _BANNED_TEXT_HINTS = ( "access denied", "forbidden", "temporarily blocked", "request blocked", "unusual traffic", "captcha", "challenge required", ) @dataclass(frozen=True) class BanTestResult: site: str url: str status: str # ok | banned | error code: int | None detail: str def _looks_banned_body(body: str) -> bool: t = (body or "").lower() return any(h in t for h in _BANNED_TEXT_HINTS) def _test_one(proxy_url: str, site: str, url: str, timeout_seconds: float) -> BanTestResult: timeout = httpx.Timeout(timeout_seconds, connect=min(8.0, timeout_seconds)) try: with httpx.Client( proxy=proxy_url, timeout=timeout, verify=False, follow_redirects=True, headers={"User-Agent": "Mozilla/5.0"}, ) as c: r = c.get(url) body = r.text[:1800] if r.text else "" if r.status_code in _BANNED_STATUS_CODES or _looks_banned_body(body): return BanTestResult(site, url, "banned", r.status_code, f"HTTP {r.status_code}") if 200 <= r.status_code < 400: return BanTestResult(site, url, "ok", r.status_code, f"HTTP {r.status_code}") return BanTestResult(site, url, "error", r.status_code, f"HTTP {r.status_code}") except Exception as e: return BanTestResult(site, url, "error", None, f"{type(e).__name__}: {e}") def run_ban_tests( proxy_url: str, timeout_seconds: float = 12.0, sites: Iterable[tuple[str, str]] = POPULAR_SITES, ) -> list[BanTestResult]: out: list[BanTestResult] = [] for site, url in sites: out.append(_test_one(proxy_url, site, url, timeout_seconds)) return out def test_single_site( proxy_url: str, site: str, url: str, timeout_seconds: float = 10.0, ) -> BanTestResult: """Probe one URL through the proxy. Used by pre-flight checks.""" return _test_one(proxy_url, site, url, timeout_seconds)