fix: preserve URL-embedded proxy auth; clearer empty-list + malformed-template errors (v0.2.2)
- _proxy_from_dict server branch falls back to auth embedded in the server URL when no explicit username/password keys are given, so it isn't dropped and the proxy keys with its credentials instead of colliding auth-less (L5) - AioProxies(proxies=[]) now raises a clear 'empty' error, not the misleading 'provide exactly one of' (nit) - a malformed template re-raises with a naming message instead of a bare str.format ValueError (nit). Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
parent
260b92b66a
commit
fc27d77000
@ -9,9 +9,9 @@ edits. **Credentials are always injected — never hardcoded.**
|
|||||||
## Install
|
## Install
|
||||||
|
|
||||||
```
|
```
|
||||||
aioproxies @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioproxies.git@v0.2.1
|
aioproxies @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioproxies.git@v0.2.2
|
||||||
# network helpers (current_ip / reset) need the extra:
|
# network helpers (current_ip / reset) need the extra:
|
||||||
aioproxies[net] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioproxies.git@v0.2.1
|
aioproxies[net] @ git+ssh://git@git.rethinkstudios.io/rethink-public/aioproxies.git@v0.2.2
|
||||||
```
|
```
|
||||||
|
|
||||||
The core has no dependencies. The `net` extra adds `aiohttp` for `current_ip` /
|
The core has no dependencies. The `net` extra adds `aiohttp` for `current_ip` /
|
||||||
|
|||||||
@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "aioproxies"
|
name = "aioproxies"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
description = "proxy parsing, formatting, health, and pool management for aiohttp/aioweb, camoufox, and socks5"
|
description = "proxy parsing, formatting, health, and pool management for aiohttp/aioweb, camoufox, and socks5"
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
dependencies = []
|
dependencies = []
|
||||||
|
|||||||
@ -18,4 +18,4 @@ __all__ = [
|
|||||||
"to_proxy",
|
"to_proxy",
|
||||||
]
|
]
|
||||||
|
|
||||||
__version__ = "0.2.1"
|
__version__ = "0.2.2"
|
||||||
|
|||||||
@ -58,6 +58,8 @@ class AioProxies:
|
|||||||
shuffle: bool = True,
|
shuffle: bool = True,
|
||||||
cooldown: int = 0,
|
cooldown: int = 0,
|
||||||
):
|
):
|
||||||
|
if proxies is not None and len(proxies) == 0:
|
||||||
|
raise ValueError("proxies list is empty; provide at least one proxy")
|
||||||
sources = [s for s in (template, proxies, static) if s]
|
sources = [s for s in (template, proxies, static) if s]
|
||||||
if len(sources) != 1:
|
if len(sources) != 1:
|
||||||
raise ValueError("provide exactly one of: template, proxies, static")
|
raise ValueError("provide exactly one of: template, proxies, static")
|
||||||
@ -129,6 +131,10 @@ class AioProxies:
|
|||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"template placeholder {exc} not provided; pass it to next(**fields)"
|
f"template placeholder {exc} not provided; pass it to next(**fields)"
|
||||||
) from exc
|
) from exc
|
||||||
|
except ValueError as exc:
|
||||||
|
# a malformed template (e.g. an unmatched '{') makes str.format raise a
|
||||||
|
# bare ValueError; re-raise naming the cause so it isn't cryptic
|
||||||
|
raise ValueError(f"malformed proxy template {self.template!r}: {exc}") from exc
|
||||||
return parse(filled)
|
return parse(filled)
|
||||||
return self._next_from_list()
|
return self._next_from_list()
|
||||||
|
|
||||||
|
|||||||
@ -133,8 +133,11 @@ def _proxy_from_dict(spec: Dict[str, str]) -> Proxy:
|
|||||||
"""normalize an aiohttp / camoufox / socks5 dict into a Proxy"""
|
"""normalize an aiohttp / camoufox / socks5 dict into a Proxy"""
|
||||||
if "server" in spec:
|
if "server" in spec:
|
||||||
proxy = _proxy_from_url(spec["server"])
|
proxy = _proxy_from_url(spec["server"])
|
||||||
user = spec.get("username")
|
# prefer explicit dict auth; otherwise fall back to auth embedded in the server
|
||||||
password = spec.get("password")
|
# URL (http://user:pass@host:port) so it isn't silently dropped — which would
|
||||||
|
# key the proxy auth-less and collide with a genuinely auth-less one
|
||||||
|
user = spec.get("username") or proxy.user
|
||||||
|
password = spec.get("password") or proxy.password
|
||||||
if user and password:
|
if user and password:
|
||||||
return Proxy(proxy.host, proxy.port, user, password)
|
return Proxy(proxy.host, proxy.port, user, password)
|
||||||
return Proxy(proxy.host, proxy.port)
|
return Proxy(proxy.host, proxy.port)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user