Files
Proxmox-VPS-Panel/backend/app/routers/console.py
T
2026-07-25 02:34:38 +03:00

76 lines
3.4 KiB
Python
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.
upstream: Optional[aiohttp.ClientWebSocketResponse] = None
session: Optional[ClientSession] = None
try:
# Небольшая задержка — Proxmox API иногда возвращает внутреннюю
# ошибку "name '_client' is not defined" при слишком быстрых
# последовательных запросах (race в API). 1 секунды обычно хватает.
if auth_kind == "cookie":
await asyncio.sleep(1.0)
session = ClientSession()
# Пробуем WebSocket-handshake с retry на случай race condition в Proxmox API.
last_exc: Optional[Exception] = None
for attempt in range(1, 4):
try:
resp = await session.get(
upstream_url,
headers=headers,
allow_redirects=False,
ssl=False if not settings.pve_verify_ssl else None,
)
logger.info(
"console_ws: attempt=%s initial GET status=%s, location=%s, body=%s",
attempt,
resp.status,
resp.headers.get("Location", "<none>"),
(await resp.text())[:200],
)
if resp.status in (301, 302, 303, 307, 308):
location = resp.headers.get("Location", "")
upstream_url = _rewrite_redirect(location, fallback_host)
logger.info("console_ws: rewritten URL to %s", upstream_url)
await resp.release()
break
elif resp.status == 101:
await resp.release()
break
elif resp.status == 502 and "name '_client' is not defined" in (await resp.text()):
# Известная внутренняя ошибка Proxmox — подождём и повторим.
await resp.release()
logger.warning(
"console_ws: Proxmox вернул race condition 502, "
"попытка %s/3 через 2с", attempt,
)
if attempt < 3:
await asyncio.sleep(2.0)
continue
else:
body = await resp.text()
await resp.release()
raise aiohttp.ClientResponseError(
request_info=resp.request_info,
history=resp.history,
status=resp.status,
message=body[:120],
headers=resp.headers,
)
except Exception as exc:
last_exc = exc
logger.warning("console_ws: attempt %s ошибка: %s", attempt, exc)
if attempt < 3:
await asyncio.sleep(2.0)
continue
else:
# Все попытки исчерпаны.
raise last_exc or RuntimeError("не удалось открыть WebSocket к Proxmox")
upstream = await session.ws_connect(
upstream_url,
headers=headers,
ssl=False if not settings.pve_verify_ssl else None,
autoclose=False,
autoping=True,
max_msg_size=8 * 1024 * 1024,
)
logger.info("console_ws: upstream connected")