Commit Graph
183 Commits
Author SHA1 Message Date
imSp4rky dfaeb83076 fix(remote): honor proxy client cdm_type for DRM system selection 2026-09-16 22:39:03 -06:00
imSp4rky ffda836442 fix(remote): return session cache for device-code and cache-only logins
Answered login prompts and uploaded cache now count as client auth; the client closes on exit and keeps the remote session alive during long downloads.
2026-09-16 19:36:31 -06:00
imSp4rky aec45e30cc feat(service): add GEOBLOCK negative geofence
Regions in GEOBLOCK refuse the service and everything else is allowed. A hit stops the run with a region error instead of auto-proxying; the check also covers proxy exits and the remote-dl client region.
2026-09-16 15:06:43 -06:00
imSp4rky aa36d4c225 feat(vaults): report bad keys to the vault that served them 2026-09-13 20:46:38 -06:00
imSp4rky a0515f8d57 feat(dl): add --proxy-download for a separate download proxy
Manifest, licence and auth stay on --proxy; track, subtitle and attachment downloads use the second proxy. Also exposed as proxy_download on the REST download job with the same server_proxy gate. The download session now ignores HTTP(S)_PROXY and copies rnet cookies set by name.
2026-09-13 14:41:01 -06:00
imSp4rky e40421a855 fix(serve): defer service hot reload while a remote session uses it
Remote-only serve no longer builds the download queue manager just to read busy services.
2026-09-13 12:21:31 -06:00
imSp4rky a7d6791136 feat(remote): verify server-CDM vault keys on the client and report bad pairs
The licence response lists KIDs a server vault supplied, the client proves them with the decode check, and a bad pair goes to the new session keys/bad route so the server flags its own row. Client vault keys go first over --remote, and the dashboard health warns when no SQLite vault can store flags.
2026-09-12 15:13:08 -06:00
imSp4rky 7c82282813 feat(vaults): flag and skip wrong content keys from poisoned vaults
Verify a vault-sourced key with an FFmpeg decode after decryption. On failure flag the KID:KEY locally with its source, restore the ciphertext, and retry through the remaining vaults and then the CDM.
2026-09-12 13:11:44 -06:00
imSp4rky 9b49299dd4 fix(config): keep no and yes as language tags 2026-09-11 20:05:46 -06:00
imSp4rky c8a674d85d fix(naming): correct language tag rule matching and add state conditions
Rules took only a scalar, so the documented list syntax raised LanguageTagError after the mux. Normalise every condition, treat an invalid tag as no match, guard the surrounding post-mux config reads, and let a rule match dual, multi and dubbed so a release can carry its own tag.
2026-09-11 20:00:08 -06:00
imSp4rky 1939ebaf79 test(api): expect a str challenge on the playready proxy licence path 2026-09-10 17:14:20 -06:00
imSp4rky d860eb9e01 fix(proxy): check the proxy exit IP before any service request
A dead proxy, or one that exits from this machine's IP, now fails with INVALID_PROXY instead of retrying every request; remote session create also builds the service off the event loop so a stuck check cannot block the server.
2026-09-10 17:08:04 -06:00
imSp4rky 2971a3a7da fix(manifests): flag DASH audio using the standard description role 2026-09-08 21:31:46 -06:00
imSp4rky 76d82df25b fix(api): keep error URLs readable and mask host paths in dashboard logs 2026-09-08 17:37:32 -06:00
imSp4rky 0b055e43ba fix(api): stop serve leaking server credentials, paths, and cross-tenant data 2026-09-08 16:43:39 -06:00
imSp4rky 84b0a92c41 feat(api): report the live title and the client's command line to the dashboard 2026-09-07 17:03:36 -06:00
imSp4rky b8c78c1a82 fix(api): tell the service that the client sent a cookie jar
A service that picks its auth path in init could only check the server's cookies directory, so a client-sent jar was invisible and the service fell back to the wrong path. The ctx now carries cookies_supplied, and a malformed cookie blob answers 400 instead of 500.
2026-09-07 13:20:55 -06:00
imSp4rky bbd26a2dc3 fix(api): let the server CDM see service-supplied keys and HLS track DRM 2026-09-07 12:30:50 -06:00
imSp4rky b91d7bfa5b fix(api): reach every PlayReady header on all server CDM routes
The rebuild raised KIDNotFound for a header whose KID lives only in the manifest, the single-track route stripped the track's other headers, and the batch cache keyed on the first PSSH alone. Licensing failures now reach the client instead of only the server log.
2026-09-07 11:54:35 -06:00
imSp4rky 8e261ae238 fix(api): license every PlayReady header in the server CDM path
extract_pssh_from_track returns the first PSSH only, so a track carrying one PlayReady object per header licensed fewer keys than the local path, which absorbs its siblings first. Relay batch licensing failures to the client too.
2026-09-07 10:59:33 -06:00
imSp4rky 7065cbf911 fix(drm): license every PlayReady header until all KIDs are covered
Only the first WRM header was read and licensed, so a manifest carrying several headers silently lost content keys. Collect KIDs from every header and license each distinct one until coverage is complete.
2026-09-07 10:05:09 -06:00
imSp4rky 627f1fa81c fix(dl): cache server-CDM keys to the local vaults
Batch and per-track remote licences read the vaults but never wrote back, so a --remote or import run kept nothing. Vault hits now replicate to the other vaults, and the server branch resolves keys under drm_lock like the local path.
2026-09-06 23:10:04 -06:00
imSp4rky d36797641d feat(dl): add --no-postscript to skip post-scripts for one run 2026-09-06 21:02:58 -06:00
imSp4rky 80f2b8f5b4 test(downloader): cover truncation and retry spin guards
Assert that an empty body of unknown length, a 206 with no complete length, and a 206 starting past the resume offset each fail instead of finalizing, and that every restart path spends an attempt.
2026-09-06 20:05:24 -06:00
imSp4rky fe7b3bb651 test(downloader): cover session state carried into download children
Assert that verify, params, cert and auth reach a spawned child, and that a mounted adapter the child cannot reproduce falls back to the single-process path. Documents --download-processes in the CLI reference.
2026-09-06 20:04:25 -06:00
imSp4rky 85503fd87c test(downloader): cover probe judging and the submission window
Assert that a probe is judged on the trailing tick, that a backoff is temporary and climbs back to the cap, and that a worker always finds its next segment staged. Documents adaptive-workers behaviour in the downloading guide.
2026-09-06 20:03:46 -06:00
imSp4rky 22cc739e83 fix(downloader): correct truncation, ranged sizing, and session carry
Check a sequential download against the complete length whenever one is known, and settle the unknown-total case on the 416. An empty body of unknown length, a 206 with no complete length, and a 206 starting past the resume offset all passed the size checks before and were renamed into place. Four restart paths spent no attempt, so a host that always answered the same way cycled forever.
2026-09-06 20:03:08 -06:00
imSp4rky dffb8b27e3 fix(serve): lock shared session state and throttle progress writes
Handlers share one service instance, so a per-session lock keeps two requests out of it at once. Track threads merge and write job state under one lock, and the progress sink coalesces ticks that say the same thing.
2026-09-06 20:01:38 -06:00
imSp4rky adea7583f0 test(services): use placeholder tags instead of real service names 2026-09-05 22:16:22 -06:00
imSp4rky 0f9997be4c refactor(drm): drop the hardcoded service branch in the license flow
One service needed session_id in its license call, which a near-duplicate of get_content_keys supplied behind a service-tag test. service_licence now passes each service only the arguments its own license function declares, so the duplicate and the branch are gone. The REST API license paths and the base PlayReady delegate get the same filtering, replacing their fixed argument set.

Two behaviour changes ride along: an empty license challenge now raises EmptyLicense for every service, not just the one, and a service that declares only challenge now receives a working call instead of a TypeError.
2026-09-05 22:14:47 -06:00
imSp4rky e845e9ba28 fix(services): name the build a compiled service is missing
A service shipped as .so/.pyd failed with a bare ModuleNotFoundError. Report the build this interpreter needs, with its version and platform.
2026-09-05 22:13:25 -06:00
imSp4rky 2f28aa8e64 fix(dl): end a cancelled track by raising instead of returning short 2026-09-05 12:52:02 -06:00
imSp4rky bae71c0194 fix(serve): resolve DRM keys for manifests with no ContentProtection PSSH
Read the init segment server-side so server_cdm licenses every track's real KID, and re-license when the manifest PSSH misses it.
2026-09-04 22:19:21 -06:00
imSp4rky dffb72e41d fix(audio): accept immersive channel layouts like 5.1.4
parse_channels rejected a three-figure layout, so a remote download crashed rebuilding the track from JSON. Add channel_total so --channels can compare either form.
2026-09-04 19:27:39 -06:00
imSp4rky 235839abc8 feat(audio): support DTS:X Profile 2 with MP4 muxing
Route titles with a dtsx/dtsy sample entry to MP4 via MP4Box, since Matroska has no CodecID for DTS-UHD. Add per-rendition HLS audio codec selection, fix merge_segments progress and its cleanup path.
2026-09-04 14:19:29 -06:00
imSp4rky e15c2f067e perf(kv): push whole services to SQL vaults in one call 2026-09-03 13:30:39 -06:00
imSp4rky 3eaf4431e2 fix(dl): repair damaged cookie files without rewriting them
Space separators, a BOM, a missing header and #HttpOnly_ rows now load; repairs happen in memory and an unparseable file raises instead of loading as empty.
2026-09-03 10:53:00 -06:00
imSp4rky c9f178f8f0 test(serve): make the session touch test clock-independent 2026-09-03 00:15:17 -06:00
imSp4rky 8354235d56 feat(serve): add operator dashboard endpoints and per-key rate limits 2026-09-02 23:52:55 -06:00
imSp4rky ac8f71b969 fix(remote): send per-track MPD fragments for service-built AdaptationSets
A service can build an AdaptationSet the served manifest does not contain, so the client's re-parse could never find it and the track downloaded with no manifest data. Those tracks now get a one-AdaptationSet MPD of their own.
2026-09-02 15:13:06 -06:00
imSp4rky f8f58f86ef fix(remote): match re-parsed manifest tracks by ID before attributes
Match once after every server manifest is parsed, and require range and bitrate in the video fallback, so a per-range ISM ladder no longer hands an HDR10 track the SDR quality level. Pass -xerror to the bsf ffmpeg calls so a failed rewrite keeps the original file instead of a near-empty one.
2026-09-01 15:06:29 -06:00
imSp4rky e00f6cca86 fix(dash): number SegmentTimeline segments from startNumber
Timeline manifests with startNumber between 2 and the segment count capped the range at the count, truncating live replays.
2026-09-01 14:05:06 -06:00
imSp4rky 7310273594 fix(ism): signal Dolby Vision and Atmos from Smooth manifests
Init segments now carry dvcC/dvvC with a profile-keyed sample entry and the dby1 brand; track ids cover the manifest URL so per-range ladders stop colliding, and the remote path carries the Atmos flag without inventing a JOC count.
2026-09-01 12:50:59 -06:00
imSp4rky dae2b37ad6 fix(serve): license multi-key PlayReady through server CDM instead of vault subset
A PlayReady WRMHEADER can advertise fewer KIDs than its multi-key license returns, so a server-vault hit on the PSSH KID alone handed every track the same key subset and failed sibling tracks. Drop the pre-license vault shortcut for PlayReady and reuse the licensed bundle per PSSH.
2026-08-31 14:38:00 -06:00
imSp4rky a01ff594da fix(remote): send only the active profile's cache files to the server
The client withheld nothing before: every profile's tokens went to any remote server. Filter by active-credential digests and profile names, keeping service-global files; worst case for a withheld file is a server-side re-auth.
2026-08-30 21:17:20 -06:00
imSp4rky f7b1446427 feat(serve): forward per-session service logs to remote-dl clients
Mirror each remote session's self.log into a bounded buffer, drained by the client via GET /api/session/{id}/logs and re-emitted locally. Server-account sessions get no relay. Also namespace service CLI options under service_params so a transport key (profile) no longer collides with a service's own option, on both the session and download-job paths.
2026-08-30 20:52:18 -06:00
imSp4rky d9b21229c3 feat(serve)!: add server-held accounts for remote sessions
serve.server_accounts lends region-tagged server credentials to remote sessions (round-robin per region, per-key opt-in, per-account cache). Remote sessions no longer fall back to the server's local credentials when the client sends none.
2026-08-28 16:36:39 -06:00
imSp4rky e3f4e52444 feat(serve): add --quiet mode and developer dashboard API
Headless serve with plain stderr logging; /api/dashboard/* (status, sessions, jobs, logs, SSE/poll events) behind a separate serve.dashboard.key.
2026-08-28 13:18:41 -06:00
imSp4rky c49fccf3b5 fix(remote): resolve service names against the remote server
Remote mode resolved names with the local alias table and built an empty stub for any unknown tag, so an unentitled service showed a blank help page. Resolve against the server's tags and aliases, and reject unknown names with the list the server does offer.
2026-08-28 10:54:21 -06:00
imSp4rky 3cb3613565 feat(remote): forward HLS segment filters to remote clients
Add POST /api/session/{id}/segment_filter: the server runs the service's OnSegmentFilter and returns only the unwanted segment URIs, so ads and bumpers are dropped over --remote-only without exposing service code.
2026-08-27 23:56:16 -06:00