Commit Graph
9 Commits
Author SHA1 Message Date
d35875e3d1 fix hls close revision file at reader deadline (#907)
* fix hls close revision file at reader deadline

Move the progressive revision reader onto its own task and feed the
response stream through a bounded channel. At the deadline the watchdog
aborts the reader, so the file handle and revision pin are released
even if a stalled client never polls the stream again.

Each open revision file now holds its own pin, so GC cannot retire a
revision while a handle is open, including one held by an in-flight
blocking read.

* fix hls close revision file at reader deadline

Move the progressive revision reader onto its own task and feed the
response stream through a bounded channel. At the deadline the watchdog
aborts the reader, so the file handle and revision pin are released
even if a stalled client never polls the stream again.

Each open revision file now holds its own pin, so GC cannot retire a
revision while a handle is open, including one held by an in-flight
blocking read.

---------

Co-authored-by: euzu <euzu@proton.me>
2026-10-09 17:41:39 +02:00
a4feb08c48 fix(hls): keep provider account across client IP changes (#895)
* fix(hls): keep provider account across client IP changes

Wrap live HLS media playlists in a single-variant master whose variant
URI is a sealed owner token, so playlist refreshes from changing client
IPs keep their owner, lease and provider affinity. Expired sessions are
recreated from the token with the same access and admission checks.

- Classify HLS resources by playlist tag, not by .m3u8 extension
- Answer non-HLS 200 bodies as failed manifests (entry: unavailable,
  refresh: 502)
- Pin child manifests and media URIs to the resolving provider account
- Add reverse_proxy.stream.hls_wrap_media_playlist (default true)
- Split AppState into app_state/ containers; move HTTP clients to core

* fix(hls): keep provider account across client IP changes

Wrap live HLS media playlists in a single-variant master whose variant
URI is a sealed owner token, so playlist refreshes from changing client
IPs keep their owner, lease and provider affinity. Expired sessions are
recreated from the token with the same access and admission checks.

- Classify HLS resources by playlist tag, not by .m3u8 extension
- Answer non-HLS 200 bodies as failed manifests (entry: unavailable,
  refresh: 502)
- Pin child manifests and media URIs to the resolving provider account
- Add reverse_proxy.stream.hls_wrap_media_playlist (default true)
- Split AppState into app_state/ containers; move HTTP clients to core

* fix(hls): keep provider account across client IP changes

Wrap live HLS media playlists in a single-variant master whose variant
URI is a sealed owner token, so playlist refreshes from changing client
IPs keep their owner, lease and provider affinity. Expired sessions are
recreated from the token with the same access and admission checks.

- Classify HLS resources by playlist tag, not by .m3u8 extension
- Answer non-HLS 200 bodies as failed manifests (entry: unavailable,
  refresh: 502)
- Pin child manifests and media URIs to the resolving provider account
- Add reverse_proxy.stream.hls_wrap_media_playlist (default true)
- Split AppState into app_state/ containers; move HTTP clients to core

* fix(hls): keep provider account across client IP changes

Wrap live HLS media playlists in a single-variant master whose variant
URI is a sealed owner token, so playlist refreshes from changing client
IPs keep their owner, lease and provider affinity. Expired sessions are
recreated from the token with the same access and admission checks.

- Classify HLS resources by playlist tag, not by .m3u8 extension
- Answer non-HLS 200 bodies as failed manifests (entry: unavailable,
  refresh: 502)
- Pin child manifests and media URIs to the resolving provider account
- Add reverse_proxy.stream.hls_wrap_media_playlist (default true)
- Split AppState into app_state/ containers; move HTTP clients to core

* fix(hls): keep provider account across client IP changes

Wrap live HLS media playlists in a single-variant master whose variant
URI is a sealed owner token, so playlist refreshes from changing client
IPs keep their owner, lease and provider affinity. Expired sessions are
recreated from the token with the same access and admission checks.

- Classify HLS resources by playlist tag, not by .m3u8 extension
- Answer non-HLS 200 bodies as failed manifests (entry: unavailable,
  refresh: 502)
- Pin child manifests and media URIs to the resolving provider account
- Add reverse_proxy.stream.hls_wrap_media_playlist (default true)
- Split AppState into app_state/ containers; move HTTP clients to core

---------

Co-authored-by: euzu <euzu@proton.me>
2026-10-02 20:16:20 +02:00
b8486cffc7 fix(hls): keep provider affinity after reconnect lease expiry (#894)
* fix(hls): keep provider affinity after reconnect lease expiry

- Remember the provider that last delivered media for reconnect-capable
  playback (HLS, DASH, Catchup, VOD) beyond the lease window. The
  preference holds no slot, never forces grace and falls back to the
  lineup when the provider is full.
- End it on provider failure, preemption, kick, timeout or admin
  terminate; stale cleanups are rejected by binding tag, request ID and
  session token. Retry token claims stay bounded.
- Terminate and kick now release the HLS binding they acquired.
- Add reverse_proxy.stream.provider_affinity_ttl_secs (default 120,
  max 86400) with Web UI field, docs and translations.
- Testkit: pause_millis steps, TTL overrides and the
  m3u-hls-provider-affinity-after-lease-expiry scenario.

* fix(hls): keep provider affinity after reconnect lease expiry

- Remember the provider that last delivered media for reconnect-capable
  playback (HLS, DASH, Catchup, VOD) beyond the lease window. The
  preference holds no slot, never forces grace and falls back to the
  lineup when the provider is full.
- End it on provider failure, preemption, kick, timeout or admin
  terminate; stale cleanups are rejected by binding tag, request ID and
  session token. Retry token claims stay bounded.
- Terminate and kick now release the HLS binding they acquired.
- Add reverse_proxy.stream.provider_affinity_ttl_secs (default 120,
  max 86400) with Web UI field, docs and translations.
- Testkit: pause_millis steps, TTL overrides and the
  m3u-hls-provider-affinity-after-lease-expiry scenario.

* fix(hls): keep provider affinity after reconnect lease expiry

- Remember the provider that last delivered media for reconnect-capable
  playback (HLS, DASH, Catchup, VOD) beyond the lease window. The
  preference holds no slot, never forces grace and falls back to the
  lineup when the provider is full.
- End it on provider failure, preemption, kick, timeout or admin
  terminate; stale cleanups are rejected by binding tag, request ID and
  session token. Retry token claims stay bounded.
- Terminate and kick now release the HLS binding they acquired.
- Add reverse_proxy.stream.provider_affinity_ttl_secs (default 120,
  max 86400) with Web UI field, docs and translations.
- Testkit: pause_millis steps, TTL overrides and the
  m3u-hls-provider-affinity-after-lease-expiry scenario.

---------

Co-authored-by: euzu <euzu@proton.me>
2026-10-01 18:55:22 +02:00
euzuandGitHub d280a5484f fix(hls): reuse stable provider lease owners across playback retries (#890)
* fix(hls): reuse stable provider lease owners across playback retries

Keep public HLS tokens unique while sharing provider leases by
client/user/channel fingerprint. Preserve request ID and binding
generation guards and scope socket cleanup to the original session.

Add regression tests for repeated retries, stale cleanup, reused
sockets and M3U alias fallback with an A=2/B=4 provider pool.

* fix(hls): reuse stable provider lease owners across playback retries
- Keep public HLS tokens unique while sharing provider leases by
client/user/channel fingerprint. Preserve request ID and binding
generation guards and scope socket cleanup to the original session.

- Add regression tests for repeated retries, stale cleanup, reused
sockets and M3U alias fallback with an A=2/B=4 provider pool.

fix: proxy external Xtream VOD sources in M3U reverse mode
- Resolve stored VOD URLs using the existing input identity.
- Use canonical movie URLs for alias accounts with the original stream ID.
- Keep redirects internal and stop forwarding upstream Referer headers.
- Add regression tests for CDN URLs, aliases, ranges, and URL leakage

* fix(hls): reuse stable provider lease owners across playback retries
- Keep public HLS tokens unique while sharing provider leases by
client/user/channel fingerprint. Preserve request ID and binding
generation guards and scope socket cleanup to the original session.

- Add regression tests for repeated retries, stale cleanup, reused
sockets and M3U alias fallback with an A=2/B=4 provider pool.

fix: proxy external Xtream VOD sources in M3U reverse mode
- Resolve stored VOD URLs using the existing input identity.
- Use canonical movie URLs for alias accounts with the original stream ID.
- Keep redirects internal and stop forwarding upstream Referer headers.
- Add regression tests for CDN URLs, aliases, ranges, and URL leakage
2026-10-01 08:16:56 +02:00
euzuandGitHub 305587f40b fix: retry unstarted streams on an available provider alias (#885)
* **Bug Fixes**
  * Playback retries can use another available provider when playback has not started, helping requests proceed if the initially selected provider is unavailable.
  * Once playback has started, retries continue using the same eligible provider to preserve playback continuity.
  * Provider selection follows the same rules for regular playback and forced reopens, reducing unnecessary provider pinning before media begins.
  * Series episode URLs can resolve to the correct account-specific playback address.
2026-09-27 10:23:35 +02:00
euzuandGitHub 278bf41d2c Fix/stalker (#884)
* **New Features**
  * Stalker playback resolves channel links on request, using available channel commands and falling back to the stored command when needed.
  * If a portal rejects a session, playback retries once after reconnecting.

* **Bug Fixes**
  * Reading playlists or resolving playback for a different portal identity no longer replaces the published catalog or clears its refresh checkpoint.
  * A failed channel playback no longer prevents other published channels from remaining available.

* **Documentation**
  * Updated Stalker playback guidance to describe on-demand link resolution and session recovery.
2026-09-26 18:56:17 +02:00
euzuandGitHub 2c07d52b93 Fixed max user connection screen when grace granted (#880)
* **Bug Fixes**
  * Improved live-stream session handling during instant grace periods, including when a session has not yet been created.
  * Corrected connection-limit and eviction tracking so active streams remain eligible for eviction even when their session record is unavailable.
  * Improved reliability when switching between live channels under connection limits.
* **Improvements**
  * Updated staged M3U overlays for Xtream providers: staged groups determine selected categories and channels, while unmatched categories remain available. Provider categories with no usable staged channels are retained.
* **Documentation**
  * Clarified how staged Xtream and M3U playlists affect provider categories and channels.
2026-09-25 08:22:11 +02:00
euzuandGitHub 6ffddc259a Provider pinned failover (#873)
- **New Features**
  - Added assertions for verifying which provider account handled the latest request.
  - Enabled provider-affine playback to fall back to another available provider when the pinned provider is unavailable.

- **Bug Fixes**
  - Improved provider fallback handling, origin request tracking, and session updates.
  - Preserved session headers when fallback stream setup fails and refreshed them after successful fallback.

- **Tests**
  - Added coverage for provider-pool failover, account reuse, limits, rejection handling, and eviction behavior.
2026-09-22 12:21:52 +02:00
euzuandGitHub 6a567d264e Feature/connection handling (#869)
* **New Features**
  * Added an opt-in runtime liveness watchdog with diagnostics, health status, and optional automatic restart.
  * Added configurable stream cleanup capacity and eviction re-entry protection.
  * Expanded configuration and UI access for users with playlist or user permissions, with safer data sanitization.
  * Added testkit scenarios and reporting for playback, admission, provider limits, sharing, and VOD behavior.
  * Added support for experimental-branch Docker builds.

* **Bug Fixes**
  * Improved provider prioritization, shared playback capacity, cleanup, reconnect handling, and concurrent client behavior.
  * Fixed playlist parsing for declared media types.
  * Release links now use the configured destination.
2026-09-19 10:17:23 +02:00