From 3bd3d1d0e874f26647f108be27c288131395b1ee Mon Sep 17 00:00:00 2001 From: SashegDev Date: Thu, 7 May 2026 17:42:15 +0000 Subject: [PATCH] Server: Cache blocklist to file + disable httpx debug logs - Blocklist now cached to data/blocklist_cache.txt - Only downloads once, then reuses cache - Disable httpx/httpcore debug logs to reduce noise --- server/main.py | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/server/main.py b/server/main.py index 633e7a9..3840026 100644 --- a/server/main.py +++ b/server/main.py @@ -1,4 +1,5 @@ import re +import logging from contextlib import asynccontextmanager from datetime import datetime from pathlib import Path @@ -12,6 +13,10 @@ from fastapi import Depends, FastAPI, HTTPException, Request, Response from fastapi.responses import FileResponse, JSONResponse from uvicorn.protocols.http.httptools_impl import HttpToolsProtocol +# Disable httpx debug logging +logging.getLogger("httpx").setLevel(logging.WARNING) +logging.getLogger("httpcore").setLevel(logging.WARNING) + from pack_manager import DATA_DIR, scan_pack, get_cached_manifest, PACKS_DIR from models import PackMeta from middleware import LoggingMiddleware @@ -37,6 +42,9 @@ import middleware as mw # Public blocklists are loaded in lifespan (once, not per-worker) MANUAL_BLOCKED_IPS = set(os.environ.get("BLOCKED_IPS", "").split(",")) - {""} +# Cache file for blocklist (load once) +BLOCKLIST_CACHE_FILE = Path("data/blocklist_cache.txt") + @asynccontextmanager async def lifespan(app: FastAPI): @@ -45,12 +53,32 @@ async def lifespan(app: FastAPI): # Initialize logging init_logging() - # Load public blocklists (only once, in main process) + # Load public blocklists (use cache if available) USE_PUBLIC_BLOCKLIST = os.environ.get("PUBLIC_BLOCKLIST", "true").lower() == "true" all_blocked = set(MANUAL_BLOCKED_IPS) + if USE_PUBLIC_BLOCKLIST: - public_ips = mw.load_public_blocklists() - all_blocked.update(public_ips) + cached_ips = set() + if BLOCKLIST_CACHE_FILE.exists(): + try: + cached_ips = set(BLOCKLIST_CACHE_FILE.read_text().strip().splitlines()) + logger.info(f"Loaded {len(cached_ips)} IPs from blocklist cache") + except Exception as e: + logger.warning(f"Failed to load blocklist cache: {e}") + cached_ips = set() + + if not cached_ips: + cached_ips = mw.load_public_blocklists() + if cached_ips: + try: + DATA_DIR.mkdir(exist_ok=True) + BLOCKLIST_CACHE_FILE.write_text("\n".join(cached_ips)) + logger.info(f"Saved {len(cached_ips)} IPs to blocklist cache") + except Exception as e: + logger.warning(f"Failed to save blocklist cache: {e}") + + all_blocked.update(cached_ips) + mw.set_ip_config(blocked=all_blocked) logger.info(f"IP blocklist loaded: {len(all_blocked)} IPs")