docs: Opus HTTP2 protocol error diagnostic
Deploy contracts-flask / validate (push) Successful in 0s
Deploy contracts-flask / validate (push) Successful in 0s
This commit is contained in:
@@ -0,0 +1,60 @@
|
|||||||
|
# Opus — ERR_HTTP2_PROTOCOL_ERROR на DrHider
|
||||||
|
|
||||||
|
29.06.2026
|
||||||
|
|
||||||
|
## Симптом
|
||||||
|
|
||||||
|
Браузер: `POST /api/drhider` → `net::ERR_HTTP2_PROTOCOL_ERROR`
|
||||||
|
|
||||||
|
curl с сервера (Linux): работает, HTTP/2, 200 OK.
|
||||||
|
Браузер пользователя (Windows, Chrome 144): ERR_HTTP2_PROTOCOL_ERROR.
|
||||||
|
|
||||||
|
## Архитектура
|
||||||
|
|
||||||
|
```
|
||||||
|
Browser → Nubes Managed Python → gunicorn (1 worker, --timeout 300) → Flask app
|
||||||
|
```
|
||||||
|
|
||||||
|
Dockerfile:
|
||||||
|
```
|
||||||
|
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--timeout", "300", "--workers", "1", "site.app:app"]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Код обработчика
|
||||||
|
|
||||||
|
```python
|
||||||
|
@app.route("/api/drhider", methods=["POST"])
|
||||||
|
def api_drhider():
|
||||||
|
from services.drhider import obfuscate_files
|
||||||
|
uploaded = request.files.getlist("files")
|
||||||
|
...
|
||||||
|
job_id = uuid.uuid4().hex
|
||||||
|
_drhider_jobs[job_id] = {"done": False, "data": None, "error": None}
|
||||||
|
|
||||||
|
def _process():
|
||||||
|
try:
|
||||||
|
from services.llm_client import HttpxLLMClient
|
||||||
|
llm = HttpxLLMClient(LLM_URL, LLM_KEY, LLM_MODEL) if LLM_KEY else None
|
||||||
|
zip_data, _csv = obfuscate_files(files, llm_client=llm)
|
||||||
|
_drhider_jobs[job_id] = {"done": True, "data": zip_data, "error": None}
|
||||||
|
except Exception as e:
|
||||||
|
_drhider_jobs[job_id] = {"done": True, "data": None, "error": str(e)}
|
||||||
|
|
||||||
|
threading.Thread(target=_process, daemon=True).start()
|
||||||
|
return jsonify({"ok": True, "job_id": job_id})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Что известно
|
||||||
|
|
||||||
|
1. curl работает (HTTP/2, 200, возвращает `{"job_id":"...","ok":true}`)
|
||||||
|
2. Браузер — ERR_HTTP2_PROTOCOL_ERROR
|
||||||
|
3. Мелкие файлы и большие — одинаково
|
||||||
|
4. До перехода на gunicorn + threading — была та же ошибка? (не уверен)
|
||||||
|
|
||||||
|
## Вопросы
|
||||||
|
|
||||||
|
1. Может ли `threading.Thread` внутри Flask/gunicorn вызывать ERR_HTTP2_PROTOCOL_ERROR?
|
||||||
|
2. Может ли проблема быть в том, что gunicorn с 1 worker не поддерживает HTTP/2 должным образом?
|
||||||
|
3. Нужно ли добавить `--worker-class` к gunicorn (gevent/eventlet) для HTTP/2?
|
||||||
|
4. Может ли Nubes-прокси перед managed-сервисом вызывать эту ошибку?
|
||||||
|
5. Что попробовать в первую очередь?
|
||||||
Reference in New Issue
Block a user