Files
forkmessager/backend/src/Docs/storage_module_documentation.md

6.9 KiB
Raw Blame History

Модуль Хранилища (Storage) - Техническая Документация

1. Обзор

Модуль Storage отвечает за централизованное управление файлами на платформе (аватары, медиа в чатах, вложения в историях). Модуль выступает абстракцией над S3-совместимым объектным хранилищем (в данный момент реализовано через MinIO) и интегрируется с криптографическим ядром для обеспечения безопасности файлов.

Ключевая особенность: модуль реализует концепцию Zero-Knowledge At-Rest Encryption — ни один файл не попадает на жесткие диски S3-сервера в открытом виде.

2. Архитектура и Процесс Загрузки

Сервис S3FileStorageService (реализация IFileStorageService из Shared Kernel) прогоняет файлы через строго определенный пайплайн:

1. Временное буферизирование

Поскольку поток загрузки (HTTP Request Stream) зачастую нельзя читать дважды (отсутствует Seek), файл сначала сохраняется во временную директорию ОС.

2. Абсолютная дедупликация (SHA-256)

Модуль вычисляет криптографический SHA-256 хэш от содержимого загруженного файла. Именно этот хэш (вместе с расширением) становится именем файла (Object Key) в корзине (Bucket) S3.

  • Результат: Если тысяча пользователей перешлет друг другу один и тот же мем (файл), физически в S3 он будет загружен и сохранен ровно один раз, колоссально экономя место на серверах.

3. "На лету" Шифрование (E2EE/At-Rest)

Далее применяется IEncryptionService (обычно AES-256-CBC). На основе временного файла открывается CryptoStream, который шифрует байты файла "на лету" во второй временный файл. Случайный Вектор Инициализации (Initalization Vector, IV) генерируется сервисом уникально для каждого файла.

4. Загрузка в S3 с Метаданными

Зашифрованный бинарник улетает в MinIO. Чувствительная информация сохраняется совершенно безопасно в заголовках метаданных объекта (MinIO Object MetaData):

  • ContentType: Исходный MIME-тип (например, image/png).
  • OriginalFileName: Закодированное исходное имя файла (Urlescaped).
  • IV: Вектор инициализации (Base64), необходимый для последующей расшифровки. Без секретного мастер-ключа приложения этот IV бесполезен.
  • EncryptionAlgorithm: Маркер алгоритма (AES-256-CBC).

В конце цикла бэкенд зачищает локальные временные файлы.

3. Процесс Скачивания и Кэширование (API)

Модуль предоставляет минималистичный REST API интерфейс, реализованный через Carter (FilesEndpoints).

Эндпоинты

Метод Маршрут Параметры Описание
GET /api/files/{id} ?download=true Отдает расшифрованный файл. Поддерживает Range запросы для стриминга видео и музыки.

Механизм In-Memory Caching (Производительность)

Расшифровка файлов (особенно видео) в реальном времени и постоянный запрос их из S3 съедает процессорное время и сетевой канал бэкенда. К эндпоинту скачивания подключен IMemoryCache:

  1. При первом запросе файла (например, аватара популярного пользователя), он скачивается из MinIO во временный файл ОС на бэкенде.
  2. Файл прогоняется через CryptoStream (с использованием IV из метаданных корзины S3) для дешифровки и выгрузки в MemoryStream.
  3. Байты готового файла, его ContentType и исходное имя кэшируются в RAM бэкенда на 30 минут (Sliding Expiration).
  4. Все последующие запросы отдают готовые байты прямо из оперативной памяти без сетевого похода в MinIO и без повторной расшифровки.

Поддержка Range-запросов

API использует метод Results.File(..., enableRangeProcessing: true). Это означает, что плееры в браузере или мобильном клиенте могут запрашивать видео кусками (например, Range: bytes=1000-2000), и бэкенд корректно отдаст только нужный чанк (из кэша или после скачивания), что делает модуль пригодным для видео-стриминга прямо из коробки.


Итог

Модуль представляет собой пуленепробиваемый шлюз для работы с медиа:

  • Обеспечивает полную конфиденциальность (ни один файл не хранится открытым в корзине облака).
  • Защищен от дубликатов (переиспользование за счет SHA-256 хэшей).
  • Высоко оптимизирован для раздачи горячего контента (In-Memory кэширование и поддержка HTTP Range Streaming).