# 2026-07-10 — Полное расследование: почему режутся файлы при загрузке ## Симптом Загрузка файлов > 64KB через веб-интерфейс loadtest обрывается. Даже чанки не проходят. ## Диагностика ### Тесты | Тест | Результат | |------|-----------| | Изнутри пода (Flask, 100KB base64) | ✅ 102400 байт, 4ms | | Снаружи (curl, 136KB URL-encoded POST) | ❌ 408 Timeout / Connection reset | | Снаружи (Python urllib, 136KB POST) | ❌ RemoteDisconnected | | Маленький POST (12 байт) | ✅ | ### Инфраструктура ``` Клиент → [прокси/LB] → nginx ingress (ModSecurity) → Flask dev-сервер (не Gunicorn!) ``` - Платформа: Shturval (managed Kubernetes) - Сервис: `loadtest.pythonk8s.dev.nubes.ru`, IP `185.247.187.151` (NUBES LLC) - Namespace: `9039a501-df2c-4b85-b049-9cd4f77e6ac0` - Deployment: `pythonk8s` - Запуск: `python app.py` (Flask dev-сервер, НЕ Gunicorn) ### ModSecurity в nginx ingress ``` SecRequestBodyLimit 13107200 # 12.5 MB — общий лимит SecRequestBodyNoFilesLimit 131072 # 128 KB — лимит для НЕ-файловых полей SecRuleEngine DetectionOnly # только логирует, не блокирует ``` Базовая строка 136KB отправляется как URL-encoded form → попадает под `NoFilesLimit`. ### Ingress-логи - Маленькие POST (146 байт) → 200 OK - Большие POST (49-65KB) → 408 Timeout через 10 секунд - `ingress_request_length` показывает 49-65KB при отправленных 136KB → тело обрезается ДО ingress (прокси/LB) ## Предыдущий опыт (contracts) Из `/home/naeel/nubes/contracts/History/`: ### `session-07-chunks.md` (v1.15-1.18) - Чанки 50KB FormData → только первый доходит - Чанки в PostgreSQL → то же самое - 7 отдельных `psycopg2.connect` на сборку → медленно → таймаут Ingress ### `session-08-upload-saga.md` (v1.12-1.26) - 26 версий до рабочей загрузки - FormData/multipart → ❌ - base64 JSON → ❌ - v1.26: `original_bytes DROP NOT NULL` + `original_b64 TEXT` → ✓ РАБОТАЛО - Потом регресс на v1.27+ ### `upload-analysis-v40.md` (v1.40) - `request.get_data(as_text=True)` + raw regex (без JSON, без b64decode, без БД) → всё равно HTTP 000 - Redis `rpush()` под подозрением - curl: 100KB — 2/5 HTTP 000, 3/5 HTTP 200 (случайно) ### `connection-reset-analysis.md` (v1.21) - HTTP 000 случайно, не зависит от размера - Health check (GET) всегда 200 - Прямой /test (JSON → БД) всегда работает ### `sonnet-upload-from-scratch.md` — ИТОГ > **"64KB — жёсткий предел платформы"** > 43 версии. FormData, JSON/base64, чанки, Redis, retry — ничего не помогло. ## Корневая причина Платформа pythonk8s (Shturval) имеет **непреодолимый предел ~64KB** на тело POST-запроса. Это не баг приложения — это ограничение инфраструктуры: - ModSecurity `SecRequestBodyNoFilesLimit` = 128KB - Прокси/LB перед ingress обрезает тело ещё сильнее (до ~50-65KB) - Ingress таймаутит через 10 секунд Ни base64, ни JSON, ни чанки не обходят этот предел. ## Ложная правка - `Dockerfile`: добавлены `--limit-request-field_size 0 --limit-request-body 0` — **бесполезно**, т.к. Gunicorn не используется - `site/app.py`: версия 1.0.4 → 1.0.5 — задеплоено, но проблему не решает ## Что дальше Для loadtest как инструмента замера скорости загрузки этот предел фатален. Нужно решать на уровне платформы: 1. Увеличить `SecRequestBodyNoFilesLimit` в ModSecurity 2. Убрать/настроить прокси/LB перед ingress 3. Либо перенести сервис на другую платформу без этих ограничений ## Источники - `/home/naeel/nubes/contracts/History/sessions/session-07-chunks.md` - `/home/naeel/nubes/contracts/History/sessions/session-08-upload-saga.md` - `/home/naeel/nubes/contracts/History/features/upload-analysis-v40.md` - `/home/naeel/nubes/contracts/History/features/upload-analysis-v41.md` - `/home/naeel/nubes/contracts/History/features/connection-reset-analysis.md` - `/home/naeel/nubes/contracts/History/features/chunk-analysis-request.md` - `/home/naeel/nubes/contracts/History/llm-analysis/sonnet-upload-from-scratch.md` - `/home/naeel/nubes/contracts/History/llm-analysis/sonnet-appjs-analysis.md`