mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
fix(m3u): forward playlist-level custom headers to external players (#1397)
* fix(m3u): forward playlist-level custom headers to external players The custom User-Agent/Referer/Origin stored on an M3U playlist only reached the built-in web players (via the Electron webRequest override). MPV/VLC and the embedded MPV player make their own HTTP requests and received only the per-channel #EXTVLCOPT values, so a playlist-wide custom User-Agent was silently dropped for UA-locked providers (#1221). External launch payloads now resolve each header independently: the channel-level #EXTVLCOPT value wins, the playlist-level value is the fallback, blank values count as absent — matching the semantics the unified favorites/recent stream resolver already had. Covers the auto-launch and catch-up effects in m3u-state, the manual MPV/VLC fallback and the embedded MPV payload in VideoPlayerComponent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011id2tdJtkJYRYX8dwYYKwL * fix(playback): send Origin as a real VLC header and cover header IPC in E2E Review follow-ups: VLC only used the Origin value as an :http-referrer fallback while MPV already sent it via --http-header-fields; both VLC paths (fresh spawn and RC enqueue) now emit the same buildHttpHeaderFields list, so a real `Origin: ...` header reaches the provider, deduplicated against an explicit headers-map Origin. The legacy origin-as-Referer fallback stays. The dash-clearkey Electron E2E now asserts the new IPC contract (blank channel-level headers arrive as undefined, not empty strings) and gains a scenario that sets a playlist-level User-Agent through the source editor and verifies the captured MPV fallback launch carries it across the renderer/main IPC boundary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011id2tdJtkJYRYX8dwYYKwL --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
1 parent
e5bb127ede
commit
9aeb83e515
10 files changed
+336
-67
No files matched your search
@@ -13,7 +13,12 @@ import {
|
||||
launchElectronApp,
|
||||
LaunchedElectronApp,
|
||||
openAddPlaylistDialog,
|
||||
openSourceEditor,
|
||||
openSources,
|
||||
saveSourceDialog,
|
||||
sourceRowByTitle,
|
||||
test,
|
||||
updateSourceDialog,
|
||||
waitForM3uCatalog,
|
||||
workspaceRoot,
|
||||
} from './electron-test-fixtures';
|
||||
@@ -479,14 +484,17 @@ test('@electron @dash ClearKey DASH filters DRM fallback and reports external la
|
||||
/web-player-diagnostic__player-card--primary/
|
||||
);
|
||||
|
||||
// Blank channel-level #EXTVLCOPT values resolve to `undefined` (not
|
||||
// empty strings) since the playlist-level header fallback landed —
|
||||
// absent means absent on the IPC boundary.
|
||||
const expectedLaunches = [
|
||||
{
|
||||
args: [
|
||||
`${fixtureServer.origin}/unsupported.mkv`,
|
||||
'Unsupported MKV',
|
||||
'',
|
||||
'',
|
||||
'',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
@@ -628,6 +636,61 @@ test('@electron @dash ClearKey DASH filters DRM fallback and reports external la
|
||||
).toBeVisible();
|
||||
await dock.getByRole('button', { name: 'Dismiss' }).click();
|
||||
await expect(dock).toBeHidden();
|
||||
|
||||
// Playlist-level custom headers must cross the IPC boundary when the
|
||||
// channel itself carries no #EXTVLCOPT values (#1221): set a
|
||||
// User-Agent on the source, relaunch the MPV fallback, and expect the
|
||||
// captured launch to carry it.
|
||||
await openSources(app.mainWindow);
|
||||
const sourceDialog = await openSourceEditor(
|
||||
app.mainWindow,
|
||||
'Imported as text'
|
||||
);
|
||||
await updateSourceDialog(sourceDialog, {
|
||||
userAgent: 'Playlist Agent E2E/1.0',
|
||||
});
|
||||
await saveSourceDialog(app.mainWindow, sourceDialog);
|
||||
await sourceRowByTitle(app.mainWindow, 'Imported as text')
|
||||
.first()
|
||||
.click();
|
||||
await waitForM3uCatalog(app.mainWindow);
|
||||
|
||||
await channelItemByTitle(app.mainWindow, 'Unsupported MKV')
|
||||
.first()
|
||||
.click();
|
||||
await expect(banner).toContainText(
|
||||
/container is likely unsupported by the browser player/i,
|
||||
{ timeout: 15_000 }
|
||||
);
|
||||
await expect(mpvFallback).toBeVisible();
|
||||
await mpvFallback.click();
|
||||
const expectedPlaylistHeaderLaunch = {
|
||||
args: [
|
||||
`${fixtureServer.origin}/unsupported.mkv`,
|
||||
'Unsupported MKV',
|
||||
'',
|
||||
'Playlist Agent E2E/1.0',
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
],
|
||||
player: 'mpv',
|
||||
} satisfies CapturedExternalPlayerLaunch;
|
||||
await expect
|
||||
.poll(() => getPlaybackRecommendationCapture(app), {
|
||||
timeout: 10_000,
|
||||
})
|
||||
.toEqual({
|
||||
closed: ['e2e-recommended-mpv-1'],
|
||||
completed: 3,
|
||||
launches: [
|
||||
...expectedBothLaunches,
|
||||
expectedPlaylistHeaderLaunch,
|
||||
],
|
||||
released: true,
|
||||
});
|
||||
} finally {
|
||||
await releasePlaybackRecommendationCapture(app).catch(() => undefined);
|
||||
await closeElectronApp(app);
|
||||
|
||||
Reference in new issue
Block a user