补上真正日常要点的那个动作:切换策略组当前选中谁

之前的面板只做了「这个入站指向哪个出站」,那是改配置文件。但 metacubexd 里点一条线路
改的根本不是入站,是策略组的当前选中——调 PUT /proxies/{组},不写文件、立刻生效。
mixed-port 走规则表,末尾 MATCH,PROXY 把流量交给 PROXY 组,所以换那个组的选中就等于
换了这个端口的出口。这是每天都要点的动作,之前整个漏了。

面板顶部现在显示完整链条(PROXY → AUTO → 某条线路),并让人在最后一个策略组上换选中。
只显示第一层等于没回答「这个端口现在走哪条线」。

透传的白名单里为此开了唯一一个写操作,单独一条路由而不是放开整个转发。
This commit is contained in:
im0o
2026-08-10 12:44:31 +08:00
parent f97981b146
commit 0062a261f7
7 changed files with 234 additions and 4 deletions
+14 -1
View File
@@ -11,7 +11,7 @@
*/
import listenerFields from '../shared/listener-fields.json' with { type: 'json' }
import { applyConfig, listBackups, readConfig, restoreBackup } from './config-store.ts'
import { kernelVersion, proxyGet } from './kernel.ts'
import { kernelVersion, proxyGet, selectProxy } from './kernel.ts'
import { tokenFromRequest, tokenMatches } from './auth.ts'
import type { ConfigObject } from '../vendor/config-editor/index.ts'
import type { Env } from './env.ts'
@@ -103,6 +103,19 @@ export function createRouter(env: Env, token: string) {
return json(await kernelVersion(env))
}
// 切换某个策略组当前选中哪个成员。这是白名单里唯一的写操作,单独开而不是放开整个透传:
// 它只改内核的运行时状态,不碰配置文件,而且是这个工具最日常的动作。
const selectMatch = /^\/api\/kernel\/proxies\/([^/]+)$/.exec(path)
if (selectMatch && req.method === 'PUT') {
const group = decodeURIComponent(selectMatch[1]!)
const body = (await req.json()) as { name?: string }
if (!body.name) return json({ error: '请求里没有 name 字段' }, 400)
const upstream = await selectProxy(env, group, body.name)
return upstream.ok
? json({ ok: true })
: json({ error: upstream.message || `内核拒绝了这次切换` }, 422)
}
if (path.startsWith('/api/kernel/') && req.method === 'GET') {
const target = path.slice('/api/kernel'.length)
if (!READABLE_KERNEL_PATHS.has(target)) {