SergeantPanda
450b384419
fix(vod_proxy): Fix stream_vod to handle session_id in path for VOD proxy URLs
2026-05-30 20:48:17 -05:00
SergeantPanda
72d1520400
feat(auth): add QueryParamJWTAuthentication for token retrieval via query parameters
...
feat(vod): include token in stream URL for episode and movie requests (Fixes #1224 )
2026-05-30 11:14:59 -05:00
SergeantPanda
61c187fc72
Merge branch 'dev' of https://github.com/Dispatcharr/Dispatcharr into pr/JCBird1012/1255
2026-05-23 21:43:13 -05:00
SergeantPanda
59587cbe66
Fix XC stream URL format output handling and improve M3U playlist generation performance. Removed unused imports in apps\output
2026-05-22 11:51:16 -05:00
SergeantPanda
17e6e8c238
chore: Cleanup unused code.
2026-05-21 10:13:28 -05:00
Jonathan Caicedo
6787e4912f
refactor: replace multiple hget calls with hmget where fields are known
...
- channel_status.py: fold output_format and output_profile_id into the
existing hmget, reducing per-client Redis calls from 3 to 1
- utils.py: collapse 2x and 3x hget per key in scan_iter loops
(get_user_active_connections) to single hmget calls
- views.py: replace 3x hget on channel metadata in the worker-join path
of stream_ts with a single hmget
2026-05-20 22:12:12 -04:00
Jonathan Caicedo
e2074c1921
fix: reduce intermittent 503s on stats page and API requests
2026-05-20 21:52:28 -04:00
SergeantPanda
594596d4f5
Enhancement: update channel card tooltip to use stable 'started_at' timestamp and refactor getStartDate utility
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
Base Image Build / prepare (push) Has been cancelled
Base Image Build / docker (amd64, ubuntu-24.04) (push) Has been cancelled
Base Image Build / docker (arm64, ubuntu-24.04-arm) (push) Has been cancelled
Base Image Build / create-manifest (push) Has been cancelled
2026-05-19 14:37:33 -05:00
SergeantPanda
a71dcb31a0
fix: ensure proper cleanup of client managers on channel disconnect
2026-05-17 19:05:44 -05:00
SergeantPanda
d448561767
Bug Fix: Refactored channel teardown to kill ffmpeg earlier in the process. Removed redundant cleanup task. Added guard to prevent multiple cleanups for the same channel.
2026-05-17 10:03:44 -05:00
SergeantPanda
c68249c314
fix: replace fork()-based subprocess with posix_spawn at all uWSGI spawn sites
...
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
Base Image Build / prepare (push) Has been cancelled
Base Image Build / docker (amd64, ubuntu-24.04) (push) Has been cancelled
Base Image Build / docker (arm64, ubuntu-24.04-arm) (push) Has been cancelled
Base Image Build / create-manifest (push) Has been cancelled
gevent registers a pthread_atfork handler that never yields. Any
subprocess.Popen/run call in a uWSGI greenlet hangs indefinitely at
fork() before the child process even starts.
- dispatcharr/gevent_patch.py: new; monkey.patch_all() + psycogreen,
loaded via uWSGI import= in all four ini files
- live_proxy/input/manager.py: posix_spawn + _SpawnedProcess; removed
dead forwarder code
- live_proxy/input/http_streamer.py: O_NONBLOCK on relay pipe + EAGAIN
retry (blocking write to a full pipe stalls the gevent hub)
- live_proxy/utils.py: new posix_spawn_proc() helper with O_NONBLOCK
stdin, shared by both output managers
- live_proxy/output/fmp4/manager.py, output/profile/manager.py:
posix_spawn_proc(); _write_all() treats EAGAIN (None) as cooperative
select.select wait instead of fatal error
- core/views.py (stream_view): posix_spawn; fixed pre-existing bug
where return StreamingHttpResponse(...) was indented inside
stream_generator, making the success path always return None
- connect/handlers/script.py: _posix_run() with posix_spawn +
cooperative select reads + non-blocking waitpid; fixes deadlock when
a script integration fires on a uWSGI-context event (client_connect
fires in the live proxy, not Celery)
2026-05-15 16:45:09 -05:00
SergeantPanda
c33d456743
Enable gevent in uWSGI workers; fix WS delivery and DB exhaustion
...
- Enable gevent cooperative multitasking in all uWSGI worker configs
(gevent-early-monkey-patch + import dispatcharr.gevent_patch)
- Rewrite WebSocket group sends to bypass asyncio in gevent workers:
_gevent_ws_send() replicates the channels_redis 4.x wire format
directly via synchronous Redis so send_websocket_update() and
_send_async() no longer fail silently after epoll is patched out
- Fix PostgreSQL connection exhaustion: CONN_MAX_AGE=0 + explicit
close_old_connections() in stream manager and cleanup watchdog loops
- Fix stream proxy race: register client before the connect-wait loop
so the cleanup watchdog never sees zero clients on a live channel
- Channel list/logo/profile queryset optimisations: conditional DISTINCT,
EXISTS semi-joins for filter-options, channel_count annotation to
eliminate N+1 in LogoSerializer, prefetched memberships in
ChannelProfileSerializer
- JsonResponse for channel ID list and summary endpoints
2026-05-14 18:55:09 -05:00
SergeantPanda
c4de8ce69e
feat: Add debug logging for profile management and client disconnect handling
2026-05-12 18:56:08 -05:00
SergeantPanda
1107423893
fix: Prevent redundant shutdown calls in StreamGenerator and clean up profile managers in ProxyServer
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
2026-05-11 17:34:54 -05:00
SergeantPanda
dc649ffd88
Enhancement: Initial fmp4 support and major ts_proxy refactor
2026-05-08 17:46:47 -05:00
SergeantPanda
883390308b
Merge pull request #1214 from sv-dispatcharr/feat/restrict-xc-user-access
...
restrict XC access per user by IP & CIDR allowlist
2026-05-03 15:41:37 -05:00
Seth Van Niekerk
0d3eed81ba
Code review changes
2026-05-02 16:59:50 -04:00
Seth Van Niekerk
a01814069a
code review & pivot
2026-05-01 09:10:37 -04:00
SergeantPanda
37922a44ab
Enhancement: Update user connection reporting in xc_get_info to reflect active connections and max connections based on user stream limits. ( Fixes #990 )
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
2026-04-30 20:33:30 -05:00
SergeantPanda
8e858045d6
Enhancement: Throttle Redis stats writes in StreamGenerator to reduce traffic during high viewer load
2026-04-30 16:23:51 -05:00
SergeantPanda
a5ac0e78fc
Enhancement: Optimize Redis writes in StreamBuffer by using pipelining for chunk storage and timestamp management
2026-04-30 16:22:36 -05:00
Seth Van Niekerk
8894d51877
restrict XC access per user by configurable IP allowlist
2026-04-28 16:35:32 -04:00
SergeantPanda
29739ede36
Enhancement: VOD start/stop notifications and system events.
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
2026-04-23 18:03:02 -05:00
SergeantPanda
eb9dd391d5
Enhancement: Consolidate client connection notifications and update timestamp handling; replace 'connected_since' with 'connected_at' for improved accuracy in duration calculations.
2026-04-23 11:03:02 -05:00
SergeantPanda
29228612aa
perf/fix: eliminate per-tick DB queries in stats; fix channel notifications
...
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
- Write channel_name (and stream_name fallback) into Redis metadata at
channel init time; read directly from Redis in get_basic_channel_info,
removing Stream and M3UAccountProfile DB queries on every stats tick
- Pass channel.name from views.py into ChannelService.initialize_channel
via new optional channel_name param, skipping the redundant Channel DB
lookup on the normal streaming path
- Pass stream_name from get_stream_info_for_switch through change_stream_url
into _update_channel_metadata, skipping the Stream DB lookup on switches
- Resolve m3u_profile_name on the frontend from the playlists store instead
of querying the DB per tick; StreamConnectionCard builds an id→profile map
- Fix channel start notification showing no name and stop notification
showing UUID: both now use channel_name from the stats WebSocket payload
2026-04-21 18:55:38 -05:00
SergeantPanda
625dab0357
Enhancement: The default profile in the M3U profiles editor now exposes Search Pattern and Replace Pattern fields
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
2026-04-21 17:20:45 -05:00
SergeantPanda
d676903825
Enhancement: Cache channel names to reduce repeated DB queries in StreamManager and StreamGenerator. This improves performance by avoiding unnecessary database calls during retries and logging events. ( Fixes #1138 )
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
2026-04-17 10:55:41 -05:00
SergeantPanda
6cd6d3ef9a
Enhancement: - **Output bitrate DB persistence**: the ffmpeg_output_bitrate stat is no longer written to the database on every FFmpeg stats tick (~2/second). Instead, a local exponential moving average (EMA, α=0.1) accumulates readings continuously. The first 10 samples (~5 seconds) are discarded as warmup to avoid polluting the average with FFmpeg's unstable ramp-up values. After warmup, the smoothed value is flushed to the database at most once every 30 seconds, and a final flush occurs when the stream stops but only if the EMA has been seeded (i.e. the stream ran past warmup). Streams that stop during warmup leave the existing database value untouched, preserving previously accurate measurements when channel-hopping.
2026-04-16 17:15:54 -05:00
SergeantPanda
f98bb183da
Bug Fix: Fixed a provider TCP connection leak in the VOD proxy
2026-04-13 19:33:22 -05:00
SergeantPanda
55048b60e3
fix(vod-proxy): prevent double profile decrement and clean up stream counter naming
2026-04-13 18:40:33 -05:00
SergeantPanda
d73071b20f
Merge branch 'dev' of https://github.com/Dispatcharr/Dispatcharr into pr/firestaerter3/1125
2026-04-13 17:42:43 -05:00
SergeantPanda
b629836b3d
Bug Fix: Fixed stream switch metadata (url, user_agent, stream_id, m3u_profile) being written to Redis before the switch was confirmed to succeed
2026-04-12 12:02:20 -05:00
SergeantPanda
65d14644b4
Bug Fix: Fixed the next_stream rotation endpoint applying the same class of bug
2026-04-12 11:36:08 -05:00
SergeantPanda
ef030b3da0
Bug Fix: Manual stream selection from the Stats page not enforcing M3U profile connection limits in multi-worker deployments
2026-04-12 10:03:46 -05:00
SergeantPanda
c3fb9c0073
security: Fixed missing network_access_allowed checks in the VOD proxy. stream_vod, head_vod, stream_xc_movie, and stream_xc_episode were not checking the STREAMS network policy, unlike the equivalent TS proxy endpoints.
2026-04-10 11:09:27 -05:00
SergeantPanda
fa9a7868ff
security: proxy streaming endpoints (stream_ts, stream_xc, stream_vod, head_vod, stream_xc_movie, stream_xc_episode) use @permission_classes([AllowAny]) (access is controlled by the per-stream-type network allow-list inside the view body); the UserAgentViewSet, StreamProfileViewSet, CoreSettingsViewSet, and ProxySettingsViewSet gained get_permissions() methods mapping read actions to IsStandardUser and write actions to IsAdmin; and AuthViewSet.logout was updated to return [Authenticated()].
2026-04-10 10:47:50 -05:00
SergeantPanda
dcefc6541c
chore(cleanup): - Removed dead VODConnectionManager class (apps/proxy/vod_proxy/connection_manager.py) and its associated helpers, which had been superseded by MultiWorkerVODConnectionManager. All active code already used the multi-worker implementation. Removed the unused VODConnectionManager import from vod_proxy/views.py, the unscheduled cleanup_vod_connections task from apps/proxy/tasks.py, and the unscheduled cleanup_vod_persistent_connections task from core/tasks.py.
...
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Waiting to run
- Removed dead VOD URL routes: `VODPlaylistView` (playlist generation), `VODPositionView` (position tracking), and the class-based `VODStatsView` (replaced by the existing function-based `vod_stats` view).
- Removed dead `updateVODPosition()` API method from `frontend/src/api.js`, which called the now-removed position tracking endpoint.
2026-04-09 19:59:50 -05:00
SergeantPanda
7f64642003
security: Hardened the HLS proxy change_stream endpoint by converting it from a plain Django view to a DRF @api_view with @permission_classes([IsAdmin]), ensuring the endpoint actually enforces admin-only access. The previous decorator arrangement (@csrf_exempt + @permission_classes) had no effect on a plain Django view.
2026-04-09 19:58:40 -05:00
None
763f42cfff
fix: pass TLS parameters to all external connection points in modular mode
...
- Add setup_pg_ssl_env() to export libpq PGSSL* env vars; all child psql/pg_dump/pg_isready commands inherit TLS automatically
- Move TLS client key permission fix before external PG connections (was running after, defeating the fix)
- Enhance key fix to trigger on ownership mismatch (root-owned 0600 key unreadable by app user)
- Extract key fix to shared script (docker/init/00-fix-pg-ssl-key.sh) sourced by both entrypoints
- Default POSTGRES_PASSWORD to empty in modular mode (cert-only auth sends no spurious password)
- Propagate TLS OPTIONS to backup pg_dump/pg_restore subprocess calls via _get_pg_env()
- Pass SSL kwargs to dropdb management command's psycopg2.connect()
- Add REDIS_SSL_PARAMS to VOD proxy Redis connections missed in original TLS PR
- Add 8-scenario TLS integration test suite (PG mTLS, Redis TLS, verify-full, key fix, Celery, regression)
- Add 6 unit tests for _get_pg_env() and dropdb TLS parameter passing
2026-03-30 20:19:27 -05:00
SergeantPanda
086cc74959
Bug Fix: M3U profile URL rewriting now uses the regex module instead of re across all URL transform code paths (url_utils.transform_url, core/views.py, vod_proxy/_transform_url, tasks.get_transformed_credentials, and the WebSocket live-preview handler in consumers.py). The regex module natively accepts JavaScript/PCRE-style named capture groups ((?<name>...)) without any conversion, eliminating the root cause of patterns that matched in the frontend live preview but failed on the backend with a re.error. As a further improvement, regex also supports variable-length lookbehind assertions (e.g. (?<=a+)), which re rejects with an error; patterns using these will now work correctly on the backend as well. Replace-pattern JS tokens are still normalised before calling regex.sub: $<name> → \g<name> and $1/$2/… → \1/\2/… (Python replacement syntax). Also fixed a bug in the WebSocket preview handler where a pattern error was incorrectly returning the search pattern string as the preview output instead of the original URL. ( Fixes #1005 )
CI Pipeline / prepare (push) Waiting to run
CI Pipeline / docker (amd64, ubuntu-24.04) (push) Blocked by required conditions
CI Pipeline / docker (arm64, ubuntu-24.04-arm) (push) Blocked by required conditions
CI Pipeline / create-manifest (push) Blocked by required conditions
Build and Push Multi-Arch Docker Image / build-and-push (push) Waiting to run
Frontend Tests / test (push) Has been cancelled
2026-03-29 17:55:08 -05:00
SergeantPanda
6d06422ddd
Enhancement: client_connect and client_disconnect system events now include the **username** of the connected user. The username is stored alongside the client metadata in Redis and included in the event payload for log_system_event calls (making it available to webhook and script integrations).
2026-03-29 16:06:14 -05:00
SergeantPanda
f00d1fe63c
Bug Fix/Enhancement:
...
- Web UI stream preview (`FloatingVideo`) was calling `mpegts.createPlayer()` with all `Config` options (e.g. `enableWorker`, `liveSync`, `headers`) merged into the first `MediaDataSource` argument. mpegts.js only reads `Config` from the optional second argument; unrecognised fields in the first are silently ignored. As a result all player configuration was effectively the library defaults — worker offloading was disabled, latency management had no effect, and the `Authorization: Bearer` header (required for user identification) was never sent. Fixed by splitting into the correct two-argument call. Both `liveBufferLatencyChasing` and `liveSync` have been disabled, eliminating playback-rate fluctuations that caused audible stuttering on live streams. SourceBuffer cleanup thresholds were also relaxed from 10s/5s to 120s/60s to prevent frequent SourceBuffer pauses.
- Web UI stream preview now sends an `Authorization: Bearer` header with each mpegts.js request, identifying the logged-in user. Live channel previews initiated from the web UI now appear on the Stats page with the correct username rather than as unknown user.
2026-03-28 18:04:11 -05:00
SergeantPanda
38f5156ca6
Enhancement: Show username in VOD cards.
2026-03-28 16:46:06 -05:00
SergeantPanda
5f4e066147
Enhancements:
...
- Connection cards on the Stats page now show the **username** of the connected user in a new User column (between IP Address and Connected). The username is resolved from the user store using the `user_id` stored in Redis client metadata; unauthenticated connections display "Anonymous". (Closes #766 )
- `ip_address` and `user_id` were not included in the client info returned by `get_detailed_channel_info()` despite being available in the Redis hash. Both fields are now extracted and returned. (Closes #586 )
2026-03-28 13:33:29 -05:00
SergeantPanda
7964b2c2cb
fix: enhance stream termination logic to handle multiple connections on the same channel
2026-03-26 20:33:03 -05:00
SergeantPanda
46d4063524
fix: change logging level from info to debug in user connection checks
2026-03-26 20:10:03 -05:00
SergeantPanda
aa6fb033d3
fix: update user stream limit checks to include media_id and rename user_limits_settings key
2026-03-26 20:02:54 -05:00
SergeantPanda
58befaa52b
fix: correct indentation in check_user_stream_limits function
2026-03-26 19:14:46 -05:00
SergeantPanda
b671a72707
fix: resolve decode_responses migration bugs and user-limit regressions
...
Fix a wave of bugs introduced by the user-priority branch's migration
from manual .decode('utf-8') calls to decode_responses=True on the
metadata Redis client:
core/utils.py
- Rewrite _init_client: fix SyntaxError at line 138, missing
redis_password/redis_user params, cls._client corruption when
decode_responses=False was requested, and dead retry backoff logic
apps/proxy/utils.py
- Fix get_user_limit_settings() → get_user_limits_settings() (2 sites)
- Fix VOD scan key vod_persistent_connections:* → vod_persistent_connection:*
- Fix undefined channel_id in VOD loop (use content_uuid from Redis hash)
- Remove leftover print(active_connections) debug statement
- Refactor manual cursor SCAN while-loops to scan_iter()
apps/channels/tasks.py
- Fix closure bug in _d(): md.get(key) → md.get(bkey) (was reading
the outer loop variable instead of the local bytes key)
apps/proxy/ts_proxy/server.py
- Replace stale b'init_time', b'total_bytes', b'state' byte-string
key lookups and .decode() calls with plain string equivalents
apps/proxy/ts_proxy/services/channel_service.py
- Fix ChannelMetadataField.STATE.encode() / .OWNER.encode() →
.STATE / .OWNER (pre-existing, broke under decoded client)
apps/proxy/ts_proxy/views.py
- Fix ChannelMetadataField.OWNER.encode("utf-8") → .OWNER
apps/proxy/ts_proxy/client_manager.py
- Fix cid.decode('utf-8') in remove_ghost_clients(): smembers()
already returns str with decode_responses=True
2026-03-26 18:41:42 -05:00
dekzter
90a600b48f
merged in dev
2026-03-26 12:17:43 -04:00