- introduce storage.Backend with S3 and local file-system implementations - deliver all blobs via signed GET/HEAD /api/objects/<key> (Range, Content-Type) - stream S3 objects through the backend; remove presigned URL path - share shared HMAC Signer between backends - remove S3_PUBLIC_URL; rename S3_PRESIGN_TTL to OBJECT_URL_TTL - make storage label in health dynamic; nginx proxy_buffering off for objects
7.3 KiB
Spec Delta
Purpose
Выбор и работа объектного хранилища: S3-совместимое (Garage) или локальная файловая система. Блобы всегда отдаются через бэкенд по подписанному URL, хранилище клиенту не раскрывается.
ADDED Requirements
Requirement: Выбор бэкенда хранилища
Система SHALL поддерживать выбор бэкенда объектного хранилища параметром конфигурации, при этом S3-совместимый бэкенд SHALL оставаться значением по умолчанию.
Scenario: Выбор S3-совместимого бэкенда
- WHEN в конфигурации задан S3-совместимый бэкенд
- THEN система хранит и отдаёт блобы через S3-совместимое хранилище
Scenario: Выбор локальной ФС
- WHEN в конфигурации задан бэкенд локальной ФС
- THEN система хранит и отдаёт блобы из каталога локальной файловой системы
Scenario: Неполная конфигурация
- WHEN конфигурация выбранного бэкенда неполна
- THEN система отказывается стартовать с явной ошибкой конфигурации
Requirement: Единая абстракция хранилища
Операции записи, чтения, удаления и проверки доступности SHALL выполняться через единый интерфейс хранилища, одинаковый для всех бэкендов; ключи объектов SHALL оставаться непрозрачными и независимыми от бэкенда.
Scenario: Ключи переносимы между бэкендами
- WHEN один и тот же ключ объекта используется на разных бэкендах
- THEN он адресует тот же логический блоб без изменения формата
Scenario: Удаление объекта
- WHEN система удаляет объект через интерфейс хранилища
- THEN блоб удаляется выбранным бэкендом
Requirement: Отдача блобов через бэкенд
Клиент SHALL получать любой блоб по URL, обслуживаемому бэкендом, с ограниченным сроком действия; ни один бэкенд SHALL не отдавать клиенту ссылку напрямую на объектное хранилище. Для анонимного доступа по share-ссылке подписанный URL SHALL быть действителен без пользовательской сессии.
Scenario: Свежий URL просмотра
- WHEN клиент запрашивает фото
- THEN система возвращает подписанный URL бэкенда со сроком действия до 1 часа
Scenario: Доступ по share-ссылке
- WHEN аноним открывает альбом по действующей share-ссылке
- THEN полученные подписанные URL позволяют загрузить фото без сессии
Scenario: Истёкшая подпись
- WHEN клиент обращается к URL с истёкшей или неверной подписью
- THEN система отказывает в доступе
Requirement: Хранилище не раскрывается клиенту
Адрес и учётные данные объектного хранилища SHALL оставаться внутренними; клиент SHALL взаимодействовать с медиа только через бэкенд, независимо от бэкенда хранения.
Scenario: S3-совместимый бэкенд
- WHEN хранилищем выбран S3-совместимый бэкенд
- THEN выдаваемый клиенту URL указывает на бэкенд, а не на S3-эндпоинт
Scenario: Локальная ФС
- WHEN хранилищем выбрана локальная ФС
- THEN выдаваемый клиенту URL указывает на бэкенд
Scenario: Хранилище недоступно извне
- WHEN объектное хранилище недоступно из внешней сети
- THEN просмотр и скачивание медиа продолжают работать
Requirement: Локальное хранение на ФС
Бэкенд локальной ФС SHALL хранить блобы в пределах заданного корневого каталога по непрозрачным ключам объектов и SHALL отвергать ключи, выводящие за пределы корня.
Scenario: Запись и чтение блоба
- WHEN система сохраняет объект с ключом
- THEN блоб размещается под корневым каталогом и позже читается по тому же ключу
Scenario: Попытка выхода из корня
- WHEN ключ содержит элементы обхода каталога
- THEN система отвергает операцию и не обращается за пределы корня
Requirement: Диапазонные запросы и тип содержимого
При отдаче блоба система SHALL возвращать корректный тип содержимого и SHALL поддерживать диапазонные запросы для докачки и больших файлов.
Scenario: Запрос диапазона
- WHEN клиент запрашивает часть блоба через диапазон
- THEN система возвращает запрошенный диапазон и соответствующий статус
Scenario: Тип содержимого
- WHEN клиент загружает блоб
- THEN ответ содержит тип содержимого, соответствующий объекту
Requirement: Доступность выбранного хранилища
Система SHALL сообщать о доступности выбранного бэкенда хранилища и отражать его в состоянии здоровья сервиса.
Scenario: Хранилище доступно
- WHEN выбранный бэкенд отвечает на проверку
- THEN состоянии здоровья отражает хранилище как доступное
Scenario: Хранилище недоступно
- WHEN выбранный бэкенд не отвечает на проверку
- THEN состояние здоровья отражает деградацию