fix/bugs #1

Merged
rs merged 14 commits from fix/bugs into master 2026-09-03 16:34:40 +00:00
Owner
No description provided.
rs added 14 commits 2026-09-03 16:26:24 +00:00
Uploads were keyed by video title while downloads and deletes used the
uuid filename, so the S3 fallback fetch always failed and objects were
never removed. The human-readable title now lives in object metadata
(x-amz-meta-filename), making downloads work across replicas and after
pod restarts without per-process state.
The /download endpoint was async but ran yt-dlp and ffmpeg inline,
freezing the event loop for the whole download and stalling probes.
Endpoints are now plain sync functions (FastAPI runs them in its
threadpool), a semaphore caps concurrent conversions, and yt-dlp gets
a socket timeout so stuck transfers cannot hold a slot forever.
Any URL was accepted and handed to yt-dlp, enabling SSRF into the
cluster and downloads from arbitrary sites. URLs are now rejected
unless scheme is http(s) and the host is a known YouTube host.
The endpoint had no throttling, so a single client could queue
unbounded conversions and exhaust CPU/disk. A sliding-window limiter
(5 requests/minute per client IP by default, configurable via
RATE_LIMIT_REQUESTS/RATE_LIMIT_WINDOW_SECONDS) returns 429 on excess.
The path parameter was joined into a filesystem path unsanitized, so
encoded slashes or '..' segments could make FileResponse serve
arbitrary files from the container. Names must now match the exact
<uuid4>.mp3 pattern or the request 404s.
Server error details (which embed yt-dlp messages containing
external video titles/URLs) and network error messages were written
via innerHTML, allowing reflected XSS. All status output now goes
through a helper that assigns textContent.
secure and cert_check were hard-coded to False, sending credentials
in cleartext even against an endpoint that could support TLS. Both now
default to secure and can be tuned with S3_SECURE/S3_CERT_CHECK env
vars; the deployment explicitly opts out until versitygw serves TLS.
Env vars were concatenated at import time (TypeError instead of a
clear error when missing) and the bucket check ran at import, so a
slow/down S3 service or a make_bucket race between replicas crashed
pods on startup. The client is now created on first use, missing env
vars raise a descriptive RuntimeError, and a concurrent bucket
creation by another pod is tolerated.
Silent 'except: pass' blocks hid S3 outages, missing files and
deletion failures, making failures undiagnosable. S3 errors, OS
errors and unexpected exceptions are now distinguished and logged;
server errors no longer masquerade as 404s. Also drops the unused
StaticFiles import.
Without a liveness probe a wedged container is never restarted.
Uses the existing /live endpoint with a start-up grace period.
Both gateway volumes were emptyDir, so every gateway restart erased
all stored objects, breaking re-downloads across pod restarts. The
data and versioning dirs now use ReadWriteOnce PVCs (10Gi/1Gi) that
survive pod rescheduling.
Unpinned requirements made image builds non-reproducible and allowed
major-version drift to break the build silently. Direct dependencies
are pinned to currently-resolving versions.
Upgrading the full base image on every build makes builds slow and
non-reproducible and rewrites the base layer cache. Only install what
the app needs (ffmpeg, no recommends) and keep pip cache out of the
image.
The workflow only pushed :latest with no tests, so regressions
shipped straight to the cluster and rollbacks had no version to pin.
A test job now runs pytest on every push, the build only runs after
it, and images are additionally tagged sha-<commit>.
rs merged commit 7fcc914ee8 into master 2026-09-03 16:34:40 +00:00
rs deleted branch fix/bugs 2026-09-03 16:34:40 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rs/ytdlp!1
No description provided.