From 997b74625d99d061af53937e55b89331ef019a08 Mon Sep 17 00:00:00 2001 From: host Date: Sat, 25 Jul 2026 00:27:55 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=84=D0=B0=D0=B9=D0=BB=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/routers/console.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/backend/app/routers/console.py b/backend/app/routers/console.py index b2f3901..cb30c31 100644 --- a/backend/app/routers/console.py +++ b/backend/app/routers/console.py @@ -9,15 +9,16 @@ 3. Проксирует бинарный VNC-поток между браузером клиента и Proxmox. Особенности Proxmox: - - PVE может вернуть HTTP redirect (302) на `https://...` вместо `wss://...` - при WebSocket-handshake. Библиотека `websockets` не умеет следовать за - такими redirect (https ≠ ws/wss), поэтому перехватываем redirect - и переписываем scheme. + - В Proxmox 8.x+ vncticket может содержать спецсимволы (#, /, %, :), + которые ломают парсинг URL (RFC 3986). Кодируем их через quote(). + - PVE может вернуть HTTP redirect (302) на `https://...` вместо `wss://...`; + перехватываем и переписываем scheme через process_redirect. """ import asyncio import logging from typing import Optional, Tuple +from urllib.parse import quote import httpx import websockets @@ -93,9 +94,14 @@ async def console_ws( guest_path = "qemu" if guest_type == "vm" else "lxc" pve_host_only = settings.pve_host.replace("http://", "").replace("https://", "") + # quote() экранирует спецсимволы в тикете и порте по правилам RFC 3986, + # не затрагивая уже экранированные символы. Без этого в Proxmox 8.x+ + # vncticket может содержать # / % : которые ломают URL. + safe_ticket = quote(ticket, safe="") + safe_port = quote(str(port), safe="") upstream_url = ( f"wss://{pve_host_only}/api2/json/nodes/{node}/{guest_path}/{vmid}/vncwebsocket" - f"?port={port}&vncticket={ticket}" + f"?port={safe_port}&vncticket={safe_ticket}" ) # Определяем способ аутентификации.