Fix IPRoyal Playwright auth: use separate fields not URL-embedded

URL-embedded credentials are silently dropped by Chromium for IPRoyal
(proxy auth never sent → every page.goto times out). Separate username/
password fields work correctly — IPRoyal responds to the 407 challenge
quickly so there is no latency penalty unlike DataImpulse (~14s).
DataImpulse keeps URL-embedded credentials to avoid that round-trip.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jtricerolph 2026-07-10 02:55:13 +00:00
parent 2b55b0d6a5
commit 218589afbe

View file

@ -98,16 +98,20 @@ def _build_auth(cfg: dict, session_id: Optional[str] = None):
def playwright_proxy(cfg: dict, session_id: Optional[str] = None) -> Optional[dict]:
"""Proxy dict for new_context(proxy=...). None when disabled.
Credentials are embedded in the server URL rather than passed as separate
fields. Separate fields cause Chromium to wait for a 407 challenge before
sending auth DataImpulse takes ~14s to issue that challenge, making every
page.goto() timeout. Embedded credentials are sent on the first CONNECT
request, bypassing the round-trip entirely.
DataImpulse: credentials embedded in the server URL separate fields cause
a ~14s 407 round-trip before DataImpulse issues a challenge.
IPRoyal: separate username/password fields URL-embedded credentials are
not parsed correctly by Chromium for this provider (auth silently dropped).
IPRoyal responds to the 407 challenge quickly so there is no latency penalty.
"""
if not is_enabled(cfg):
return None
from urllib.parse import quote
user, pwd = _build_auth(cfg, session_id)
server = f"http://{cfg['host']}:{cfg['port']}"
if _provider(cfg) == 'iproyal':
return {'server': server, 'username': user, 'password': pwd}
from urllib.parse import quote
return {
'server': f"http://{quote(user, safe='')}:{quote(pwd, safe='')}@{cfg['host']}:{cfg['port']}",
}