From 218589afbe8592dfe33e88d77b48f63d98f689d7 Mon Sep 17 00:00:00 2001 From: jtricerolph Date: Fri, 10 Jul 2026 02:55:13 +0000 Subject: [PATCH] Fix IPRoyal Playwright auth: use separate fields not URL-embedded MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- backend/services/proxy.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/backend/services/proxy.py b/backend/services/proxy.py index 07e3c90..b9313bc 100644 --- a/backend/services/proxy.py +++ b/backend/services/proxy.py @@ -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']}", }