Files
quoter/docs/upload-api-detailed.md
Untone 6c3262edbe
Some checks failed
Deploy / deploy (push) Has been skipped
CI / lint (push) Failing after 8s
CI / test (push) Failing after 3m57s
simpler-auth+no-overlay
2025-09-01 20:36:15 +03:00

299 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 📤 API загрузки файлов с квотами - Точная документация
## Обзор
Quoter предоставляет API для загрузки файлов с системой квот и автоматической обработкой различных типов медиа.
## Базовый URL
```
http://localhost:8080
```
## Аутентификация
Все эндпоинты загрузки требуют JWT токен в заголовке:
```
Authorization: Bearer <jwt-token>
```
---
## 📤 Загрузка файлов (УЛУЧШЕННАЯ ВЕРСИЯ)
### POST /
Загружает файл(ы) в S3-совместимое хранилище (Storj) с улучшенной проверкой квот и валидацией.
#### Заголовки запроса
```http
Authorization: Bearer <jwt-token>
Content-Type: multipart/form-data
```
#### Параметры
- **file** (required) - файл(ы) для загрузки в multipart/form-data
#### Поддерживаемые форматы
Автоматическое определение MIME-типа из содержимого файла:
- **Изображения**: JPEG, PNG, GIF, WebP, HEIC
- **Видео**: MP4, WebM, AVI
- **Аудио**: MP3, WAV, OGG
- **Документы**: PDF
#### 🔄 Улучшенная логика обработки
1. **Проверка авторизации** - извлечение и валидация JWT токена
2. **Получение текущей квоты** пользователя из Redis
3. **Предварительная проверка квоты** - пользователь не достиг лимита
4. **Streaming чтение файла** с проверками на каждом chunk:
- Проверка лимита одного файла (500 МБ)
- Проверка общей квоты пользователя
5. **Пропуск пустых файлов**
6. **Определение MIME-типа** из содержимого (не из расширения!)
7. **Генерация UUID имени** файла с правильным расширением
8. **Загрузка в Storj S3**
9. **Обновление квоты** пользователя
10. **Сохранение метаданных** в Redis (с обработкой ошибок)
#### Ограничения
- **Максимальная квота на пользователя**: 5 ГБ (5,368,709,120 байт)
- **Максимальный размер одного файла**: 500 МБ (524,288,000 байт)
- **Проверка квоты происходит во время чтения** (streaming)
- **Поддержка множественных файлов** в одном запросе
#### Успешные ответы
**Один файл:**
```http
HTTP/1.1 200 OK
Content-Type: text/plain
```
**Несколько файлов:**
```http
HTTP/1.1 200 OK
Content-Type: application/json
```
#### Коды ошибок (ИСПРАВЛЕННЫЕ)
| Код | Условие | Описание |
|-----|---------|----------|
| **400 Bad Request** | Нет файлов | `"No files provided or all files were empty"` |
| **401 Unauthorized** | Отсутствует токен | `"Authorization token required"` |
| **401 Unauthorized** | Неверный токен | `"Invalid authorization token"` |
| **413 Payload Too Large** | 🎯 Превышена квота | `"Author quota limit exceeded"` |
| **413 Payload Too Large** | 🎯 Большой файл | `"Single file size limit exceeded"` |
| **413 Payload Too Large** | 🎯 Превышение при загрузке | `"Author quota limit would be exceeded"` |
| **415 Unsupported Media Type** | Неподдерживаемый MIME | `"Unsupported file format"` |
| **415 Unsupported Media Type** | Нет расширения для MIME | `"Unsupported content type"` |
| **500 Internal Server Error** | Ошибка S3 | `"File upload failed"` |
| **500 Internal Server Error** | Ошибка квоты | `"Failed to update user quota"` |
#### ✅ Исправленные проблемы
1. **Правильный код ошибки для квоты**: 413 Payload Too Large
2. **Efficient memory usage**: streaming с проверками на каждом chunk
3. **Предварительная проверка квоты** перед началом загрузки
4. **Лимит размера одного файла**: 500 МБ
5. **Улучшенная обработка ошибок** с детальными сообщениями
6. **Поддержка множественных файлов** в одном запросе
7. **Детальное логирование** с процентом использования квоты
---
#### 🔄 Как это работает
1. **JWT декодирование** - извлекается `user_id` из токена
2. **Redis lookup** - опциональный поиск сессии по ключу `session:{user_id}:{token}`
3. **Quota lookup** - получение квоты по ключу `quota:{user_id}` из Redis
4. **Activity update** - обновление `last_activity` timestamp (если сессия найдена)
5. **Response building** - объединение данных пользователя и квоты
#### Заголовки запроса
```http
Authorization: Bearer <jwt-token>
```
#### Успешный ответ
```http
HTTP/1.1 200 OK
Content-Type: application/json
```
#### Поля ответа
| Поле | Тип | Описание |
|------|-----|----------|
| `user_id` | string | Уникальный ID пользователя |
| `username` | string \| null | Имя пользователя |
| `token_type` | string \| null | Тип токена (обычно "session") |
| `created_at` | string \| null | Unix timestamp создания сессии |
| `last_activity` | string \| null | Unix timestamp последней активности |
| `auth_data` | string \| null | JSON-строка с данными авторизации |
| `device_info` | string \| null | JSON-строка с информацией об устройстве |
| `quota.current_quota` | number | Текущее использование квоты в байтах |
| `quota.max_quota` | number | Максимальная квота в байтах |
| `quota.usage_percentage` | number | Процент использования квоты |
#### Коды ошибок
| Код | Условие | Описание |
|-----|---------|----------|
| **401 Unauthorized** | Отсутствует токен | `"Authorization token required"` |
| **401 Unauthorized** | Неверный JWT | `"Invalid or expired session token"` |
| **401 Unauthorized** | Сессия не найдена | `"Session not found or expired"` |
#### Примеры использования
```bash
# Получение информации о текущем пользователе
curl -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc..." \
http://localhost:8080/
```
---
## 📊 Управление квотами
### GET /quota
Получает информацию о квоте пользователя.
#### Параметры запроса
```
GET /quota?user_id=<user_id>
```
#### Ответ
```json
{
"user_id": "user123",
"current_quota": 1073741824,
"max_quota": 5368709120
}
```
### POST /quota/increase
Увеличивает квоту пользователя (admin-only).
#### Тело запроса
```json
{
"user_id": "user123",
"additional_bytes": 1073741824
}
```
#### Валидация
- `additional_bytes` должно быть > 0
- Требуется админский токен
### POST /quota/set
Устанавливает абсолютное значение квоты (admin-only).
#### Тело запроса
```json
{
"user_id": "user123",
"new_quota_bytes": 2147483648
}
```
---
## 🔍 Получение файлов
### GET /{filename}
Возвращает файл по имени с возможными трансформациями.
#### Параметры URL
- `filename` - имя файла или имя_размер.расширение для миниатюр
#### Query параметры
- `s=<shout_id>` - добавляет оверлей с данными shout (только изображения)
#### Примеры
```bash
GET /uuid-file.jpg # Оригинальный файл
GET /uuid-file_300.jpg # Миниатюра 300px
GET /uuid-file_300.jpg/webp # Миниатюра в WebP
GET /uuid-file.jpg?s=123 # С оверлеем shout
```
---
## 🧪 Примеры использования
### Загрузка файла
```bash
curl -X POST http://localhost:8080/ \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc..." \
-F "file=@photo.jpg"
```
**Ответ при успехе:**
```
c4ca4238-a0b9-23f1-8429-81dc9bdb9a1f.jpg
```
**Ответ при превышении квоты:**
```
HTTP/1.1 401 Unauthorized
Quota exceeded
```
### Проверка квоты
```bash
curl "http://localhost:8080/quota?user_id=user123" \
-H "Authorization: Bearer admin-token"
```
### Увеличение квоты (admin)
```bash
curl -X POST http://localhost:8080/quota/increase \
-H "Authorization: Bearer admin-token" \
-H "Content-Type: application/json" \
-d '{"user_id": "user123", "additional_bytes": 1073741824}'
```
---
## 🔧 Рекомендации по улучшению
1. **Исправить код ошибки квоты**: 401 → 413
2. **Добавить предварительную проверку размера** из Content-Length
3. **Streaming загрузка** вместо полного чтения в память
4. **Лимит размера одного файла**
5. **Детальная валидация MIME-типов**
6. **Метрики использования квот**
---
*Документация актуальна для версии кода на момент создания. Для изменений см. CHANGELOG.md.*