refactor: consolidate health-check HTTP logic in pool
Extract _http_check() to deduplicate identical HTTP GET + status parsing between _test_proxy and _test_chain. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -233,16 +233,13 @@ class ProxyPool:
|
||||
|
||||
# -- health testing ------------------------------------------------------
|
||||
|
||||
async def _test_proxy(self, key: str, entry: ProxyEntry) -> bool:
|
||||
"""Test a single proxy by building the full chain and sending HTTP GET."""
|
||||
async def _http_check(self, chain: list[ChainHop]) -> bool:
|
||||
"""Send an HTTP GET through *chain* and return True on 2xx."""
|
||||
parsed = urlparse(self._cfg.test_url)
|
||||
host = parsed.hostname or "httpbin.org"
|
||||
port = parsed.port or 80
|
||||
path = parsed.path or "/"
|
||||
|
||||
chain = self._chain + [entry.hop]
|
||||
entry.last_test = time.time()
|
||||
entry.tests += 1
|
||||
try:
|
||||
reader, writer = await build_chain(
|
||||
chain, host, port, timeout=self._cfg.test_timeout,
|
||||
@@ -267,39 +264,17 @@ class ProxyPool:
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
async def _test_proxy(self, key: str, entry: ProxyEntry) -> bool:
|
||||
"""Test a single proxy by building the full chain and sending HTTP GET."""
|
||||
entry.last_test = time.time()
|
||||
entry.tests += 1
|
||||
return await self._http_check(self._chain + [entry.hop])
|
||||
|
||||
async def _test_chain(self) -> bool:
|
||||
"""Test the static chain without any pool proxy."""
|
||||
if not self._chain:
|
||||
return True
|
||||
|
||||
parsed = urlparse(self._cfg.test_url)
|
||||
host = parsed.hostname or "httpbin.org"
|
||||
port = parsed.port or 80
|
||||
path = parsed.path or "/"
|
||||
|
||||
try:
|
||||
reader, writer = await build_chain(
|
||||
self._chain, host, port, timeout=self._cfg.test_timeout,
|
||||
)
|
||||
except (ProtoError, TimeoutError, ConnectionError, OSError, EOFError):
|
||||
return False
|
||||
|
||||
try:
|
||||
request = f"GET {path} HTTP/1.1\r\nHost: {host}\r\nConnection: close\r\n\r\n"
|
||||
writer.write(request.encode())
|
||||
await writer.drain()
|
||||
|
||||
line = await asyncio.wait_for(reader.readline(), timeout=self._cfg.test_timeout)
|
||||
parts = line.decode("utf-8", errors="replace").split(None, 2)
|
||||
return len(parts) >= 2 and parts[1].startswith("2")
|
||||
except (TimeoutError, ConnectionError, OSError, EOFError):
|
||||
return False
|
||||
finally:
|
||||
try:
|
||||
writer.close()
|
||||
await writer.wait_closed()
|
||||
except OSError:
|
||||
pass
|
||||
return await self._http_check(self._chain)
|
||||
|
||||
async def _run_health_tests(self, keys: list[str] | None = None) -> None:
|
||||
"""Test proxies with bounded concurrency.
|
||||
|
||||
Reference in New Issue
Block a user