feat: add proxy template origin field and implement socket utilities for log streaming
This commit is contained in:
@@ -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]
|
||||
Reference in New Issue
Block a user