Skip to content

Commit 1ba4919

Browse files
committed
refactor(proxy-checker): improve probe coverage, logging, and error reporting
- Rename `ip` -> `device_ip` on `ProxyChecker` to clarify intent. - Add verbose logging for country lookup when `verbose=True`. - Iterate TLS versions per protocol (test multiple TLS levels for HTTPS proxies). - Collect `send_query` error messages grouped by protocol and TLS (messages[protocol][tls]). - Add `messages` field to `ProxyChekerResult` to return detailed per-protocol/TLS errors. - Update tests to use `device_ip` and simplify test invocation formatting. This refactor improves diagnostics and robustness when probing proxies across protocol/TLS combinations.
1 parent 357041f commit 1ba4919

3 files changed

Lines changed: 52 additions & 34 deletions

File tree

‎proxy_checker/ProxyChecker.py‎

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ def __init__(self, timeout: int = 30000, verbose: bool = False):
1818
self.timeout = timeout
1919
self.verbose = verbose
2020

21-
self.ip = get_device_ip(timeout=self.timeout, verbose=self.verbose)
22-
if not self.ip:
21+
self.device_ip = get_device_ip(timeout=self.timeout, verbose=self.verbose)
22+
if not self.device_ip:
2323
print("ERROR: cannot get device ip")
2424

2525
# ProxyAnonymity helper used for parsing judge responses
@@ -37,6 +37,8 @@ def get_country(self, ip: str) -> list:
3737
timeout=self.timeout,
3838
verbose=self.verbose,
3939
)
40+
if self.verbose:
41+
print(f"Country lookup for IP {ip}: {r}")
4042
if r and not getattr(r, "error", False) and (r.response or "").startswith("1"):
4143
fields = (r.response or "").split(";")
4244
return [fields[3], fields[1]]
@@ -111,39 +113,55 @@ def check_proxy(
111113
else:
112114
protocols_to_test = all_protocols
113115

116+
tls_to_test = []
117+
if isinstance(tls, str) and tls in ["1.3", "1.2", "1.1", "1.0"]:
118+
tls_to_test.append(tls)
119+
else:
120+
tls_to_test = ["1.3", "1.2", "1.1", "1.0"]
121+
114122
protocols: Dict[str, QueryResult] = {}
115123
latencies = []
124+
# messages[protocol][tls] = message string or None
125+
messages: Dict[str, Dict[str, Optional[str]]] = {}
116126

117127
for _ in range(retries):
118128
for proto in protocols_to_test:
119-
# Query a fixed probe URL using the protocol-prefixed proxy URL
120-
proxy_url = f"{proto}://{proxy}"
121-
result = send_query(
122-
url=test_url or "https://www.google.com",
123-
proxy=proxy_url,
124-
user=user,
125-
password=password,
126-
tls=tls,
127-
timeout=timeout if timeout is not None else self.timeout,
128-
verbose=self.verbose,
129-
)
130-
if not result or result.error:
131-
continue
132-
133-
protocols[proto] = result
134-
t = getattr(result, "total_time", None)
135-
if t is not None:
136-
latencies.append(t * 1000)
137-
138-
if not check_all_protocols:
139-
break
129+
for tls in tls_to_test:
130+
proxy_url = f"{proto}://{proxy}"
131+
result = send_query(
132+
url=test_url or "https://www.google.com",
133+
proxy=proxy_url,
134+
user=user,
135+
password=password,
136+
tls=tls,
137+
timeout=timeout if timeout is not None else self.timeout,
138+
verbose=self.verbose,
139+
)
140+
# capture message for this protocol/tls attempt
141+
msg = (
142+
getattr(result, "message", None) if result is not None else None
143+
)
144+
if not result or result.error:
145+
messages.setdefault(proto, {})[tls] = msg
146+
continue
147+
148+
protocols[proto] = result
149+
# mark success for this tls version
150+
messages.setdefault(proto, {})[tls] = None
151+
t = getattr(result, "total_time", None)
152+
if t is not None:
153+
latencies.append(t * 1000)
154+
155+
if not check_all_protocols:
156+
break
140157

141158
if not protocols:
142159
return ProxyChekerResult(
143160
protocols=[],
144161
anonymity="",
145162
latency=0,
146163
response="",
164+
messages=messages,
147165
country=None,
148166
country_code=None,
149167
proxy=None,
@@ -182,6 +200,7 @@ def check_proxy(
182200
anonymity=anonymity,
183201
latency=latency,
184202
response=sample_response,
203+
messages=messages,
185204
country=country[0],
186205
country_code=country[1],
187206
proxy=remote_addr,

‎proxy_checker/ProxyChekerResult.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from typing import List, Optional, Union, Literal
33
from dataclasses import asdict
44
import json
5+
from typing import Dict
56

67

78
@dataclass
@@ -10,6 +11,8 @@ class ProxyChekerResult:
1011
anonymity: Union[Literal["Transparent", "Anonymous", "Elite"], str]
1112
latency: int
1213
response: Optional[str] = None
14+
# messages[protocol][tls] = message string or None
15+
messages: Optional[Dict[str, Dict[str, Optional[str]]]] = None
1316
country: Optional[str] = None
1417
country_code: Optional[str] = None
1518
proxy: Optional[str] = None

‎tests/ProxyChecker_test.py‎

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
1-
from proxy_checker import ProxyChecker
1+
from proxy_checker import ProxyChecker, get_device_ip
22

33
checker = ProxyChecker(verbose=False)
4-
print(f"my IP {checker.ip}")
5-
proxy = "157.175.43.137:797"
6-
ip = proxy.split(":")[0]
7-
print(f"proxy IP {ip}")
4+
print(f"my IP {checker.device_ip}")
5+
proxy = "16.78.41.33:9011"
6+
proxy_ip = proxy.split(":")[0]
7+
print(f"proxy IP {proxy_ip}")
88
result = checker.check_proxy(
9-
proxy=proxy,
10-
check_all_protocols=True,
11-
check_address=True,
12-
check_country=True,
13-
retries=4,
9+
proxy=proxy, check_all_protocols=True, check_address=True, check_country=True
1410
)
1511
print(result)
1612
print(f"latency: {result.latency} ms")
1713
print(f"anonymity: {result.anonymity}")
18-
print(f"is proxy ip same {checker.ip == ip}")
14+
print(f"is device ip same {checker.device_ip == proxy_ip}")
1915
print(f"country: {result.country} ({result.country_code})")

0 commit comments

Comments
 (0)