From fa4c9a91cab3a45f87696f8addafe05cbd933d03 Mon Sep 17 00:00:00 2001 From: grossmj Date: Sat, 10 Apr 2021 13:01:23 +0930 Subject: [PATCH] Add symbol dimensions endpoint and SSL support for packet capture with remote HTTPS server. --- gns3server/api/routes/controller/symbols.py | 16 ++++++++++++++++ gns3server/controller/__init__.py | 15 +++++++++++---- gns3server/utils/http_client.py | 9 +++++---- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/gns3server/api/routes/controller/symbols.py b/gns3server/api/routes/controller/symbols.py index c85ea7c3..fa94a1d2 100644 --- a/gns3server/api/routes/controller/symbols.py +++ b/gns3server/api/routes/controller/symbols.py @@ -57,6 +57,22 @@ async def get_symbol(symbol_id: str): return ControllerNotFoundError("Could not get symbol file: {}".format(e)) +@router.get("/{symbol_id:path}/dimensions", + responses={404: {"model": schemas.ErrorMessage, "description": "Could not find symbol"}}) +async def get_symbol_dimensions(symbol_id: str): + """ + Get a symbol dimensions. + """ + + controller = Controller.instance() + try: + width, height, _ = controller.symbols.get_size(symbol_id) + symbol_dimensions = {'width': width, 'height': height} + return symbol_dimensions + except (KeyError, OSError, ValueError) as e: + return ControllerNotFoundError("Could not get symbol file: {}".format(e)) + + @router.post("/{symbol_id:path}/raw", status_code=status.HTTP_204_NO_CONTENT) async def upload_symbol(symbol_id: str, request: Request): diff --git a/gns3server/controller/__init__.py b/gns3server/controller/__init__.py index 8981fb48..901761a7 100644 --- a/gns3server/controller/__init__.py +++ b/gns3server/controller/__init__.py @@ -51,6 +51,7 @@ class Controller: self._computes = {} self._projects = {} + self._ssl_context = None self._notification = Notification(self) self.gns3vm = GNS3VM(self) self.symbols = Symbols() @@ -82,15 +83,14 @@ class Controller: self._load_controller_settings() - ssl_context = None if server_config.getboolean("ssl"): if sys.platform.startswith("win"): log.critical("SSL mode is not supported on Windows") raise SystemExit - ssl_context = self._create_ssl_context(server_config) + self._ssl_context = self._create_ssl_context(server_config) protocol = server_config.get("protocol", "http") - if ssl_context and protocol != "https": + if self._ssl_context and protocol != "https": log.warning("Protocol changed to 'https' for local compute because SSL is enabled".format(port)) protocol = "https" try: @@ -104,7 +104,7 @@ class Controller: password=server_config.get("password", ""), force=True, connect=True, - ssl_context=ssl_context) + ssl_context=self._ssl_context) except ControllerError: log.fatal("Cannot access to the local server, make sure something else is not running on the TCP port {}".format(port)) sys.exit(1) @@ -140,6 +140,13 @@ class Controller: raise SystemExit return ssl_context + def ssl_context(self): + """ + Returns the SSL context for the server. + """ + + return self._ssl_context + def _update_config(self): """ Call this when the server configuration file changes. diff --git a/gns3server/utils/http_client.py b/gns3server/utils/http_client.py index 79d5639e..279f80af 100644 --- a/gns3server/utils/http_client.py +++ b/gns3server/utils/http_client.py @@ -30,9 +30,10 @@ class HTTPClient: _aiohttp_client: aiohttp.ClientSession = None @classmethod - def get_client(cls) -> aiohttp.ClientSession: + def get_client(cls, ssl_context=None) -> aiohttp.ClientSession: if cls._aiohttp_client is None: - cls._aiohttp_client = aiohttp.ClientSession(connector=aiohttp.TCPConnector(family=socket.AF_INET)) + connector = aiohttp.TCPConnector(family=socket.AF_INET, ssl_context=ssl_context) + cls._aiohttp_client = aiohttp.ClientSession(connector=connector) return cls._aiohttp_client @classmethod @@ -42,9 +43,9 @@ class HTTPClient: cls._aiohttp_client = None @classmethod - def request(cls, method: str, url: str, user: str = None, password: str = None, **kwargs): + def request(cls, method: str, url: str, user: str = None, password: str = None, ssl_context=None, **kwargs): - client = cls.get_client() + client = cls.get_client(ssl_context=ssl_context) basic_auth = None if user: if not password: