mirror of
https://github.com/CloakHQ/CloakBrowser.git
synced 2026-06-23 11:41:46 +02:00
* fix(proxy): log when SOCKS5 credential auto-encoding rewrites URL (#157) Auto URL-encoding of SOCKS5 credentials (added in v0.3.26 to fix Chromium's '=' truncation bug) currently happens silently. Users debugging connectivity have no way to know the wrapper rewrote their proxy URL — the original #157 thread took 8 round-trips to surface this exact ambiguity. Emit a log when re-encoding actually changes the URL: INFO on Python's 'cloakbrowser' logger, console.debug in JavaScript. Stays silent on already-encoded inputs and credential-less URLs to avoid false-positive noise. Credentials are not included in the log message. Tests: 3 new cases per language (Python caplog, JS vi.spyOn console.debug) covering trigger / silent-when-encoded / silent-when-no-creds. * fix(proxy): gate log on credential change, not full URL diff Per Copilot review on #209: urlparse cosmetically lowercases scheme and hostname, so comparing the full reconstructed URL to the input would emit "Auto URL-encoded SOCKS5..." even for inputs like `socks5://USER:pass@HOST.com:1080` where no credential encoding happened. Compare raw vs encoded user/password substrings instead. Mirror the same condition in JS for parity (JS's manual parser preserves case today, but the credential-level compare is more robust against future changes). Adds one regression test per language.
This commit is contained in:
+19
-3
@@ -813,6 +813,10 @@ def _normalize_socks_string_url(url: str) -> str:
|
||||
truncate them at special chars like '='. Idempotent: pre-encoded input stays
|
||||
the same (decoded then re-encoded).
|
||||
|
||||
Emits an INFO log when re-encoding actually changes the URL, so users who
|
||||
previously hit silent SOCKS5 fallback (#157) can see what the wrapper did.
|
||||
Silent on already-encoded inputs (no false-positive noise).
|
||||
|
||||
On unparseable input (invalid port, broken IPv6 literal, etc.) logs a
|
||||
warning and returns the original string — preserves pre-fix pass-through
|
||||
behavior so Chromium's own error handling kicks in.
|
||||
@@ -828,18 +832,30 @@ def _normalize_socks_string_url(url: str) -> str:
|
||||
# urlparse returns None for absent components, "" for present-but-empty.
|
||||
if parsed.username is None and parsed.password is None:
|
||||
return url
|
||||
enc_user = quote(unquote(parsed.username), safe="") if parsed.username else ""
|
||||
raw_user = parsed.username or ""
|
||||
enc_user = quote(unquote(raw_user), safe="") if raw_user else ""
|
||||
# Preserve the colon separator when password component is present, even if
|
||||
# empty, so `user:@host` stays `user:@host`.
|
||||
if parsed.password is not None:
|
||||
enc_pass = quote(unquote(parsed.password), safe="") if parsed.password else ""
|
||||
raw_pass = parsed.password
|
||||
enc_pass = quote(unquote(raw_pass), safe="") if raw_pass else ""
|
||||
else:
|
||||
raw_pass = None
|
||||
enc_pass = None
|
||||
return _assemble_socks_url(
|
||||
normalized = _assemble_socks_url(
|
||||
parsed.scheme, parsed.hostname or "", parsed.port,
|
||||
enc_user, enc_pass,
|
||||
parsed.path, parsed.params, parsed.query, parsed.fragment,
|
||||
)
|
||||
# Compare credentials, not the full URL: urlparse cosmetically lowercases
|
||||
# scheme and hostname, so a full-string compare would falsely fire on
|
||||
# `socks5://USER:pass@HOST.com:1080` even when no encoding work happened.
|
||||
if enc_user != raw_user or enc_pass != raw_pass:
|
||||
logger.info(
|
||||
"Auto URL-encoded SOCKS5 proxy credentials (special characters "
|
||||
"detected). Pre-encode the URL to suppress this notice."
|
||||
)
|
||||
return normalized
|
||||
|
||||
|
||||
def _extract_proxy_url(proxy: str | ProxySettings | None) -> str | None:
|
||||
|
||||
Reference in New Issue
Block a user