Files
transcriber/tasks/items/serve-content-for-file-ranges.md
T
av 75c6f0168a учёт: закрыт переезд хранилища, заведён урожай его ревью
- storage-without-pocketbase закрыта как реализованная: приёмка сошлась по всем
  пяти критериям записи и по двенадцати приёмочным свойствам рубрики ревью
  дизайна, работа лежит коммитом c9b7765
- урожай триажа ревью развёрнут в одиннадцать записей с тегом партии
  review-2026-08-23 и расставлен по зависимости, а не в конец списка
- находка про признак живости воркера слита в stalled-pipeline-metric: у неё та
  же причина — вставший конвейер неотличим от простоя
2026-08-23 08:41:49 +03:00

3.6 KiB
Raw Blame History

🧹 Отдавать файл записи через http.ServeContent

  • Тип: chore
  • Категория: Очередь — Стандартная семантика диапазонов нужна проигрыванию записи на экране: браузер тянет звук именно диапазонами
  • Зачем: Отдача файла считает диапазоны байт своей рукой — около 110 строк семантики HTTP, которую стандартная библиотека делает сама, и на этих строках стоит проигрывание записи на экране.
  • Теги: review-2026-08-23

Отдача файла записи разбирает заголовок Range, считает границы, ставит Content-Range и код 206 своей рукой — около 110 строк семантики HTTP. http.ServeContent делает то же самое: диапазоны, If-Range, Last-Modified, ETag, неверный диапазон с кодом 416.

Своя реализация стоит не тем, что длиннее, а тем, что расходится: браузер проигрывает звук именно диапазонами, и задача play-recording-in-app встанет поверх этих строк.

Нашёл проход review-architecture (вторая половина R2) ревью change 2026-08-23-storage-without-pocketbase.

Затрагивает

  • internal/controller/http/file.go — разбор Range, ответ 206 и заголовки диапазона;
  • тип содержимого ответа: он выводится из закрытого перечня форматов и остаётся за нами, ServeContent его не выбирает;
  • открытие копии в internal/adapter/repo/sqlite/store.goServeContent требует io.ReadSeeker и время последнего изменения;
  • публичный контракт HTTP: коды 200, 206, 416 и заголовки ответа на запрос файла.

Критерии приёмки

  • Диапазоны считает стандартная библиотека. Оракул: grep по internal/controller/http — ни одного разбора заголовка Range руками, вызов http.ServeContent один.
  • Ответы на диапазон не изменились. Оракул: тест контроллера — запрос без Range отдаёт 200 и всю длину, запрос bytes=0-99 отдаёт 206 с Content-Range, запрос за пределом длины отдаёт 416.
  • Тип содержимого по-прежнему выбирает сервис. Оракул: тест на записи с расширением .html — ответ несёт application/octet-stream и attachment, а не тип из имени.
  • Чужой файл остаётся недостижимым. Оракул: прежний тест владения — чужая и несуществующая запись отвечают байт в байт одинаково.

Рамки

Раскладку каталога данных и имена копий не трогаем: она объявлена необратимой. Ответ на запрос чужого файла не меняется ни кодом, ни телом.