From 05bdc4dfc8ad9c5d18cfdc121651fd2dc32e666a Mon Sep 17 00:00:00 2001 From: rustic-monkey Date: Wed, 24 Apr 2024 21:01:52 -0500 Subject: [PATCH] Check if proxy server is host-able before running Log differences in origins when updated Load repeated timers into a list --- pyfilebrowser/main.py | 8 ++++++++ pyfilebrowser/proxy/main.py | 18 ++++++++++++++---- pyfilebrowser/proxy/server.py | 18 ++++++++++-------- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/pyfilebrowser/main.py b/pyfilebrowser/main.py index 367bea9..adfeb0b 100644 --- a/pyfilebrowser/main.py +++ b/pyfilebrowser/main.py @@ -2,6 +2,7 @@ import logging import multiprocessing import os +import socket import subprocess import time import warnings @@ -176,6 +177,13 @@ def background_tasks(self, auth_map: Dict[str, str]) -> None: if self.proxy: assert proxy_settings.port != int(self.env.config_settings.server.port), \ f"\n\tProxy server can't run on the same port [{proxy_settings.port}] as the server!!" + try: + with socket.socket() as sock: + sock.bind((proxy_settings.host, proxy_settings.port)) + except OSError as error: + self.logger.error(error) + self.logger.critical("Cannot initiate proxy server") + raise log_config = struct.LoggerConfig(self.logger).get() if proxy_settings.debug: log_config = struct.update_log_level(log_config, logging.DEBUG) diff --git a/pyfilebrowser/proxy/main.py b/pyfilebrowser/proxy/main.py index e211a80..f8dc12f 100644 --- a/pyfilebrowser/proxy/main.py +++ b/pyfilebrowser/proxy/main.py @@ -1,3 +1,4 @@ +import difflib import json import logging import time @@ -12,6 +13,7 @@ LOGGER = logging.getLogger('proxy') CLIENT = httpx.Client() +DIFFER = difflib.Differ() epoch = lambda: int(time.time()) # noqa: E731 @@ -25,11 +27,19 @@ def refresh_allowed_origins() -> None: - | The background task runs only when the env vars, ``private_ip`` or ``public_ip`` is set to True, | as they are the only dynamic values. """ - LOGGER.debug("Refreshing allowed origins") + allowed_origins = set() + allowed_origins.update(settings.env_config.origins) + allowed_origins.update(settings.allowance()) + + # Extract elements that are only in one of the sets + if difference := [item for item in list(DIFFER.compare(sorted(settings.session.allowed_origins), + sorted(allowed_origins))) + if item.startswith('- ') or item.startswith('+ ')]: + LOGGER.warning("Changes in allowed origins: %s", difference) + settings.session.allowed_origins.clear() - settings.session.allowed_origins.update(settings.env_config.origins) - settings.session.allowed_origins.update(settings.allowance()) - LOGGER.debug("Next refresh - %s", + settings.session.allowed_origins = allowed_origins + LOGGER.debug("Refreshed allowed origins. Next refresh - %s", (datetime.now() + timedelta(seconds=settings.env_config.origin_refresh)).strftime('%c')) diff --git a/pyfilebrowser/proxy/server.py b/pyfilebrowser/proxy/server.py index 5bf1650..77a6244 100644 --- a/pyfilebrowser/proxy/server.py +++ b/pyfilebrowser/proxy/server.py @@ -36,20 +36,21 @@ def run_in_parallel(self, logger: logging.Logger) -> None: uvicorn_access.disabled = True uvicorn_access.propagate = False assert logger.name == "proxy" - timer = None + timers = [] if settings.env_config.origin_refresh and \ (settings.env_config.private_ip or settings.env_config.public_ip): - logger.info("Initiating background task to refresh allowed origins every %d seconds", - settings.env_config.origin_refresh) - timer = repeated_timer.RepeatedTimer( + timers.append(repeated_timer.RepeatedTimer( function=main.refresh_allowed_origins, interval=settings.env_config.origin_refresh - ) + )) + for timer in timers: + logger.info("Initiating the background task '%s' with interval %d seconds", + timer.function.__name__, timer.interval.real) timer.start() try: self.run() except KeyboardInterrupt: - if timer: - logger.info("Stopping background task to refresh allowed origins") + for timer in timers: + logger.info("Stopping the background task '%s'", timer.function.__name__) timer.stop() finally: logger.info("Proxy service terminated") @@ -75,7 +76,8 @@ def proxy_server(server: str, settings.destination.url = server settings.destination.auth_config = auth_map - main.refresh_allowed_origins() + settings.session.allowed_origins.update(settings.env_config.origins) + settings.session.allowed_origins.update(settings.allowance()) # noinspection HttpUrlsUsage logger.info("Starting proxy engine on http://%s:%s with %s workers",