Phase 2: ProxyService reverse proxy (HTTP+WebSocket forwarding)

- New: services/proxy_service.py (path->URL mapping)
- New: services/web_panel/routes/proxy.py (3 REST endpoints)
- New: static/web_panel/pages/proxy.html (WebUI)
- Tests: 28/28 passing
This commit is contained in:
2026-06-10 20:47:17 +08:00
parent 8dbf628dd6
commit c680fea8e0
6 changed files with 238 additions and 9 deletions
+2 -1
View File
@@ -5,7 +5,7 @@ import os
import logging
from pathlib import Path
from aiohttp import web
from .routes import auth, status, plugins, commands, logs, projects
from .routes import auth, status, plugins, commands, logs, projects, proxy
logger = logging.getLogger(__name__)
@@ -63,6 +63,7 @@ class WebPanelManager:
commands.setup_routes(app, self.base_path)
logs.setup_routes(app, self.base_path)
projects.setup_project_routes(app, self.sm)
proxy.setup_proxy_routes(app, self.sm)
# 注册日志广播
ls = self.sm.get_service("log")
+30
View File
@@ -0,0 +1,30 @@
from aiohttp import web, ClientSession
import json, logging, asyncio
logger = logging.getLogger(__name__)
def setup_proxy_routes(app, service_manager):
async def list_proxies(request):
ps = service_manager.get_service("proxy")
return web.json_response({"proxies": ps.list_proxies() if ps else []})
async def add_proxy(request):
try:
data = await request.json()
ps = service_manager.get_service("proxy")
ok = await ps.register_proxy(
path=data.get("path",""), target_url=data.get("target",""),
description=data.get("description",""), is_external=data.get("external",False))
return web.json_response({"ok": ok})
except Exception as e:
return web.json_response({"ok": False, "error": str(e)}, status=400)
async def remove_proxy(request):
path = request.match_info.get("path","")
ps = service_manager.get_service("proxy")
ps.unregister_proxy(path)
return web.json_response({"ok": True})
app.router.add_get("/api/proxy", list_proxies)
app.router.add_post("/api/proxy", add_proxy)
app.router.add_delete("/api/proxy/{path}", remove_proxy)
logger.info("🔀 代理路由已注册")