feat: add proxy template origin field and implement socket utilities for log streaming
This commit is contained in:
@@ -4,12 +4,23 @@ import shutil
|
||||
import signal
|
||||
from pathlib import Path
|
||||
|
||||
import yaml
|
||||
|
||||
from app.integrations.docker import change_port
|
||||
from app.integrations.docker.ports import get_random_port
|
||||
from app.models.proxy import ProxyDocument
|
||||
from app.services.mitmproxy.options import MitmOptionError, validate_options
|
||||
from app.services.mitmproxy.runtime_files import (
|
||||
conf_dir_for,
|
||||
config_path_for,
|
||||
ensure_log_path,
|
||||
log_path_for,
|
||||
read_cmdline,
|
||||
read_log_tail,
|
||||
remove_dir,
|
||||
remove_file,
|
||||
script_path_for,
|
||||
write_config,
|
||||
write_script,
|
||||
)
|
||||
from app.services.mitmproxy.runtime_validation import (
|
||||
ReservedProxyPortError,
|
||||
ensure_proxy_port_not_reserved,
|
||||
@@ -300,23 +311,13 @@ class MitmdumpManager:
|
||||
return candidate
|
||||
|
||||
async def write_script(self, proxy: ProxyDocument) -> Path:
|
||||
path = self.script_path_for(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
|
||||
return await write_script(self.work_dir, proxy)
|
||||
|
||||
async def write_config(self, proxy: ProxyDocument) -> Path:
|
||||
path = self.config_path_for(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
|
||||
return await write_config(self.work_dir, proxy)
|
||||
|
||||
async def log_path(self, proxy: ProxyDocument) -> Path:
|
||||
path = self.log_path_for(proxy)
|
||||
await asyncio.to_thread(path.parent.mkdir, parents=True, exist_ok=True)
|
||||
return path
|
||||
return await ensure_log_path(self.work_dir, proxy)
|
||||
|
||||
async def spawn(self, command: list[str], log_path: Path):
|
||||
with log_path.open("ab") as log_file:
|
||||
@@ -408,49 +409,28 @@ class MitmdumpManager:
|
||||
return expected_script in cmdline and expected_confdir in cmdline
|
||||
|
||||
def read_cmdline(self, 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]
|
||||
return read_cmdline(pid)
|
||||
|
||||
def script_path_for(self, proxy: ProxyDocument) -> Path:
|
||||
return self.work_dir / "addons" / f"{proxy.proxy_port}.py"
|
||||
return script_path_for(self.work_dir, proxy)
|
||||
|
||||
def conf_dir_for(self, proxy: ProxyDocument) -> Path:
|
||||
return self.work_dir / "conf" / str(proxy.proxy_port)
|
||||
return conf_dir_for(self.work_dir, proxy)
|
||||
|
||||
def config_path_for(self, proxy: ProxyDocument) -> Path:
|
||||
return self.conf_dir_for(proxy) / "config.yaml"
|
||||
return config_path_for(self.work_dir, proxy)
|
||||
|
||||
def log_path_for(self, proxy: ProxyDocument) -> Path:
|
||||
return self.work_dir / "logs" / f"{proxy.proxy_port}.log"
|
||||
return log_path_for(self.work_dir, proxy)
|
||||
|
||||
async def read_log_tail(self, 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()
|
||||
return await read_log_tail(path, limit=limit)
|
||||
|
||||
def remove_file(self, path: Path) -> None:
|
||||
try:
|
||||
path.unlink(missing_ok=True)
|
||||
except OSError:
|
||||
return
|
||||
remove_file(path)
|
||||
|
||||
def remove_dir(self, path: Path) -> None:
|
||||
try:
|
||||
shutil.rmtree(path)
|
||||
except FileNotFoundError:
|
||||
return
|
||||
except OSError:
|
||||
return
|
||||
remove_dir(path)
|
||||
|
||||
def lock_for(self, proxy_port: int) -> asyncio.Lock:
|
||||
lock = self.locks.get(proxy_port)
|
||||
|
||||
Reference in New Issue
Block a user