fix(xtream): send player-style User-Agent to avoid WAF challenge blocking connections (#1170)

Some Xtream panels sit behind Cloudflare/WAF rules that challenge generic
browser-looking User-Agents while allowlisting known IPTV player clients.
The previous hardcoded, truncated browser-style User-Agent in
xtream.events.ts (XTREAM_REQUEST and XTREAM_PROBE_URL) was being served a
Cloudflare challenge page (HTTP 403 HTML) instead of the real API response,
so "Test Connection" always failed with "Could not connect to the portal"
even though the same portal worked fine via curl (with a player-style UA)
and Safari. Switching to a shared VLC-style User-Agent constant across all
three request sites resolves it, verified against a live panel.

Co-authored-by: Sergio Herencias Redondo <sherencr@MacBook-Pro-de-diverzy.local>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-07-11 20:49:12 +02:00
1 parent 09764e24d4
commit f856226dc3
3 files changed
+63 -6

No files matched your search

@@ -62,6 +62,19 @@ targets. Those targets are validated when registered and revalidated before the
`/xtream` proxy request, including protocol, URL credentials, DNS resolution,
and private-network checks.
## User-Agent
Electron's `XTREAM_REQUEST` and `XTREAM_PROBE_URL` handlers
(`apps/electron-backend/src/app/events/xtream.events.ts`) send a shared
`XTREAM_CLIENT_USER_AGENT` constant on every outgoing request. Some Xtream
panels sit behind a WAF (e.g. Cloudflare) configured to challenge
generic/incomplete browser-looking User-Agents while allowlisting known IPTV
player clients; a player-style User-Agent (currently a VLC signature) avoids
that challenge page, whereas a browser-looking but non-browser TLS/HTTP client
(axios/curl with a Chrome or empty User-Agent) can be blocked even though a
real browser or a VLC-style client passes. Keep all three request sites using
the shared constant instead of inlining the string again.
## Playback URL Formats
When account info includes `user_info.allowed_output_formats`, the current