feat: add proxy template origin field and implement socket utilities for log streaming

This commit is contained in:
gabdevele
2026-05-07 10:54:57 +02:00 Unverified
parent 53dcdafdb1
commit 354ec150bc
32 changed files with 1681 additions and 1214 deletions
@@ -0,0 +1,82 @@
import asyncio
import shutil
from pathlib import Path
import yaml
from app.models.proxy import ProxyDocument
def script_path_for(work_dir: Path, proxy: ProxyDocument) -> Path:
return work_dir / "addons" / f"{proxy.proxy_port}.py"
def conf_dir_for(work_dir: Path, proxy: ProxyDocument) -> Path:
return work_dir / "conf" / str(proxy.proxy_port)
def config_path_for(work_dir: Path, proxy: ProxyDocument) -> Path:
return conf_dir_for(work_dir, proxy) / "config.yaml"
def log_path_for(work_dir: Path, proxy: ProxyDocument) -> Path:
return work_dir / "logs" / f"{proxy.proxy_port}.log"
async def write_script(work_dir: Path, proxy: ProxyDocument) -> Path:
path = script_path_for(work_dir, proxy)
await asyncio.to_thread(path.parent.mkdir, parents=True, exist_ok=True)
await asyncio.to_thread(path.write_text, proxy.code, encoding="utf-8")
return path
async def write_config(work_dir: Path, proxy: ProxyDocument) -> Path:
path = config_path_for(work_dir, proxy)
await asyncio.to_thread(path.parent.mkdir, parents=True, exist_ok=True)
options = {"block_global": False, **proxy.mitm_options}
config_text = yaml.safe_dump(options, sort_keys=True)
await asyncio.to_thread(path.write_text, config_text, encoding="utf-8")
return path
async def ensure_log_path(work_dir: Path, proxy: ProxyDocument) -> Path:
path = log_path_for(work_dir, proxy)
await asyncio.to_thread(path.parent.mkdir, parents=True, exist_ok=True)
return path
async def read_log_tail(path: Path, limit: int = 4000) -> str:
if not await asyncio.to_thread(path.exists):
return ""
content = await asyncio.to_thread(
path.read_text,
encoding="utf-8",
errors="replace",
)
return content[-limit:].strip()
def remove_file(path: Path) -> None:
try:
path.unlink(missing_ok=True)
except OSError:
return
def remove_dir(path: Path) -> None:
try:
shutil.rmtree(path)
except FileNotFoundError:
return
except OSError:
return
def read_cmdline(pid: int) -> list[str]:
path = Path(f"/proc/{pid}/cmdline")
try:
raw = path.read_bytes()
except OSError:
return []
decoded = raw.decode("utf-8", errors="replace")
return [part for part in decoded.split("\x00") if part]