Reviewer concerns: 1. POST /api/proxy/restart only saved config (reload), did not restart the listener. Now it touches data/restart.signal; proxy watcher polls that file separately and force-restarts the listener even when config is unchanged. 2. Editing proxy.listen_port via UI could break Docker port mapping (compose publishes 25565:25565 only). UI now shows it read-only; README documents how to change it together with compose. - proxy/main.py: ProxyState.check_restart_signal() + watcher uses it - api/config_io.py: touch_restart_signal() helper - api/routes/status.py: /api/proxy/restart -> touch_restart_signal() - frontend Settings: disabled listen_port input + 프록시 재시작 button - README + .gitignore updated
63 lines
2.0 KiB
Python
63 lines
2.0 KiB
Python
"""프록시 상태 및 통계."""
|
|
from __future__ import annotations
|
|
|
|
import sqlite3
|
|
import time
|
|
|
|
from fastapi import APIRouter
|
|
|
|
from config_io import LOG_DB, load_config, touch_restart_signal
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/status")
|
|
def status() -> dict:
|
|
cfg = load_config()
|
|
total = allowed = blocked = errored = 0
|
|
last_ts: float | None = None
|
|
if LOG_DB.exists():
|
|
con = sqlite3.connect(LOG_DB)
|
|
try:
|
|
total = con.execute("SELECT COUNT(*) FROM connections").fetchone()[0]
|
|
allowed = con.execute(
|
|
"SELECT COUNT(*) FROM connections WHERE action='allowed'"
|
|
).fetchone()[0]
|
|
blocked = con.execute(
|
|
"SELECT COUNT(*) FROM connections WHERE action='blocked'"
|
|
).fetchone()[0]
|
|
errored = con.execute(
|
|
"SELECT COUNT(*) FROM connections WHERE action='error'"
|
|
).fetchone()[0]
|
|
row = con.execute(
|
|
"SELECT ts FROM connections ORDER BY id DESC LIMIT 1"
|
|
).fetchone()
|
|
last_ts = row[0] if row else None
|
|
finally:
|
|
con.close()
|
|
return {
|
|
"proxy_enabled": cfg.get("proxy", {}).get("enabled", True),
|
|
"listen_port": cfg.get("proxy", {}).get("listen_port"),
|
|
"backend": cfg.get("backend"),
|
|
"domain_count": len(cfg.get("allowed_domains", [])),
|
|
"stats": {
|
|
"total": total,
|
|
"allowed": allowed,
|
|
"blocked": blocked,
|
|
"error": errored,
|
|
"last_event_ts": last_ts,
|
|
},
|
|
"server_time": time.time(),
|
|
}
|
|
|
|
|
|
@router.post("/proxy/restart")
|
|
def restart_proxy() -> dict:
|
|
"""프록시 listener 를 강제로 stop → start 시킨다.
|
|
|
|
config 가 바뀌지 않았어도 listener 자체를 재시작하기 때문에 단순
|
|
config reload 와는 다르다. (proxy watcher 가 별도 신호 파일을 폴링)
|
|
"""
|
|
ts = touch_restart_signal()
|
|
return {"ok": True, "restart_signal_ts": ts}
|