Fix validation: 0 valid proxies (httpx shared client bug)

httpx.AsyncClient.get() does not accept proxy= per-request.
Shared client caused every check_one call to raise TypeError,
silently caught as False, so 0/N proxies ever passed.

Reverted to per-proxy AsyncClient(proxy=url) in _check_one.
Semaphore concurrency + wall-clock cap preserved.
Also re-adds _check_one helper that was accidentally removed.

Made-with: Cursor
This commit is contained in:
Dr Jones
2026-04-16 01:12:56 -07:00
parent c9c45fdfec
commit 0509d4104d

View File

@@ -65,49 +65,33 @@ async def validate_proxies(
(check_url[:70] + "") if len(check_url) > 70 else check_url,
)
t = httpx.Timeout(timeout_seconds, connect=min(8.0, timeout_seconds))
lim = max(32, min(256, c * 8))
limits = httpx.Limits(max_connections=lim, max_keepalive_connections=max(16, c * 4))
last_prog_t = 0.0
prog_step = max(1, total // 120)
async def _run_all(client: httpx.AsyncClient) -> None:
async def one(u: str) -> None:
nonlocal done, last_prog_t
async with sem:
good = await _check_one(u, check_url, timeout_seconds)
async with lock:
done += 1
if good:
ok.append(u)
if on_progress:
now = time.monotonic()
if (
done == total
or done == 1
or done % prog_step == 0
or (now - last_prog_t) >= 0.1
):
last_prog_t = now
on_progress(done, total)
async def one(u: str) -> None:
nonlocal done, last_prog_t
async with sem:
try:
r = await client.get(check_url, proxy=u)
good = r.status_code == 200 and len(r.content) > 0
except Exception:
good = False
async with lock:
done += 1
if good:
ok.append(u)
if on_progress:
now = time.monotonic()
if (
done == total
or done == 1
or done % prog_step == 0
or (now - last_prog_t) >= 0.1
):
last_prog_t = now
on_progress(done, total)
async def _run_all() -> None:
await asyncio.gather(*(one(u) for u in proxy_urls))
try:
async with httpx.AsyncClient(
timeout=t,
verify=False,
follow_redirects=True,
limits=limits,
) as client:
await asyncio.wait_for(_run_all(client), timeout=cap)
await asyncio.wait_for(_run_all(), timeout=cap)
except asyncio.TimeoutError:
log.warning(
"validate_proxies wall-clock cap %.0fs exceeded (%d URLs) — returning partial results",
@@ -118,6 +102,22 @@ async def validate_proxies(
return ok
async def _check_one(proxy_url: str, check_url: str, timeout_seconds: float) -> bool:
"""Check a single proxy by fetching check_url through it. True = live and returns 200."""
t = httpx.Timeout(timeout_seconds, connect=min(8.0, timeout_seconds))
try:
async with httpx.AsyncClient(
proxy=proxy_url,
timeout=t,
verify=False,
follow_redirects=True,
) as c:
r = await c.get(check_url)
return r.status_code == 200 and len(r.content) > 0
except Exception:
return False
async def check_chain_exit_ip(
listen_proxy: str,
check_url: str,