Proxy.as_string() and ProxyHelper.asString() pasted the username and
password into scheme://user:pass@host:port unencoded. A password holding
`#`, `/` or `?` made the URL unparseable (requests: InvalidURL, impit:
"Failed to build Impit instance"), so public_ip() and proxy_exit_geo()
reported a working proxy as dead; a password holding `%41` parsed but was
decoded, and the gateway was sent `A` instead. Playwright gets the
credentials as separate fields, so only the lookup was affected.
Encode both with quote(safe='') / encodeURIComponent. Checked against a
local proxy recording Proxy-Authorization: requests and impit both decode
the encoded form back to the exact credentials.
Reported-by: alkaz-nodemaven (https://github.com/daijro/camoufox/issues/823)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>