Выдача чужих задач (критично). GET /api/tasks отдавал карточки ВСЕХ пользователей вместе со ссылками и названиями, и по взятому оттуда id любой мог забрать чужой готовый файл: неугадываемость идентификатора была единственной защитой, а список её обнулял. Эндпоинт не использовался фронтендом и удалён; идентификатор задачи расширен до полного uuid4. Исчерпание потоков. Каждая задача поднимала свой поток, который до получаса ждал на семафоре: шесть запусков в минуту с одного адреса давали около 180 висящих потоков при TasksMax=256, то есть сервис ложился с двух IP. Заменено очередью с постоянным пулом из трёх воркеров; переполнение отвечает честным 503 сразу, а не молчаливым ожиданием. Проверено: число потоков не растёт с числом задач. Обход выбора формата. Регулярка пропускала ключевые слова селектора, и format_id=all заставлял yt-dlp скачать все дорожки сразу. Такие слова теперь отвергаются явно. Переполнение диска. max_filesize у yt-dlp проверяется по Content-Length и не работает для фрагментированных и chunked-потоков — такой поток качался бы без ограничения. Добавлен сторож в progress hook: раз в пять секунд проверяет накопленный размер и свободное место, прерывая задачу. Это Proxmox-хост, заполненный раздел — авария гипервизора, а не сервиса. Утечка внутренностей. Текст ошибки yt-dlp уходил пользователю как есть и мог содержать локальные пути, имя пользователя и внутренние адреса. Теперь пути и адреса вымарываются, а непредвиденные исключения наружу показываются общим сообщением и пишутся в журнал. Молчаливые сбои. Уборщик глушил любые исключения без единой строчки в журнале: при потере прав на запись файлы перестали бы удаляться, диск бы заполнился, а журнал остался бы пустым. Добавлено логирование сбоев уборщика и ошибок загрузок (только домен, не полный URL). Зависший индикатор. Клиент закрывал EventSource навсегда при любом разрыве, поэтому после перезапуска сервера карточка вечно висела на «Обработка…». Теперь переподключается, а после пяти неудач честно сообщает о потере связи. Скорость. Включена параллельная загрузка фрагментов: DASH-фрагменты тянулись строго по одному, и скорость упиралась в задержку до сервера. Замер на том же ролике: было около 8 МБ/с, стало 29 МБ/с. Шрифты. Inter перенесён на свой сервер: запрос к Google блокировал отрисовку и попутно отдавал им IP каждого посетителя, что противоречило обещанию на главной. Внешних запросов со страниц не осталось. Интерфейс. Селектор звуковой дорожки в режиме «Видео» назывался «Аудио» так же, как отдельный режим, и создавал впечатление, что MP3 пропал. Переименован в «Звук в видео» с пояснением, где искать MP3. README приведён в соответствие: он утверждал, что не хранится ни ссылок, ни адресов, хотя лента их хранит. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AwY2Cg54RK7WZdvMaLV5Di
47 KiB
47 KiB