From 1f85abb0363a7266ece0749c6ef5807c56b7c010 Mon Sep 17 00:00:00 2001 From: grossmj Date: Sat, 18 Feb 2023 15:32:57 +0800 Subject: [PATCH] Fix broken websocket console with Python 3.11 --- gns3server/compute/base_node.py | 13 ++++++++++++- gns3server/handlers/api/controller/node_handler.py | 5 +++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/gns3server/compute/base_node.py b/gns3server/compute/base_node.py index 9a522d6e..54dea0d6 100644 --- a/gns3server/compute/base_node.py +++ b/gns3server/compute/base_node.py @@ -469,7 +469,18 @@ class BaseNode: try: # keep forwarding websocket data in both direction - await asyncio.wait([ws_forward(telnet_writer), telnet_forward(telnet_reader)], return_when=asyncio.FIRST_COMPLETED) + if sys.version_info >= (3, 11, 0): + # Starting with Python 3.11, passing coroutine objects to wait() directly is forbidden. + aws = [asyncio.create_task(ws_forward(telnet_writer)), asyncio.create_task(telnet_forward(telnet_reader))] + else: + aws = [ws_forward(telnet_writer), telnet_forward(telnet_reader)] + + done, pending = await asyncio.wait(aws, return_when=asyncio.FIRST_COMPLETED) + for task in done: + if task.exception(): + log.warning(f"Exception while forwarding WebSocket data to Telnet server {task.exception()}") + for task in pending: + task.cancel() finally: log.info("Client has disconnected from console WebSocket") if not ws.closed: diff --git a/gns3server/handlers/api/controller/node_handler.py b/gns3server/handlers/api/controller/node_handler.py index c2d23e80..c9e7c057 100644 --- a/gns3server/handlers/api/controller/node_handler.py +++ b/gns3server/handlers/api/controller/node_handler.py @@ -29,6 +29,9 @@ from gns3server.schemas.node import ( NODE_DUPLICATE_SCHEMA ) +import logging +log = logging.getLogger(__name__) + class NodeHandler: """ @@ -500,6 +503,8 @@ class NodeHandler: await ws.send_bytes(msg.data) elif msg.type == aiohttp.WSMsgType.ERROR: break + except ConnectionResetError: + log.info("Websocket console connection with compute disconnected") finally: if not ws.closed: await ws.close()