mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-11-12 20:27:23 +00:00
feat(gateway): 插件可注册自定义对外挂载点(R3)
用户需求:插件与适配器可以注册对外服务的端口。 现状是插件端点被固定在 /api/plugins/http/ 下。那条限制有三个理由 (可 grep / 可整体撤销 / 不能影子内核路由),放开时必须逐条补回来: - 命名空间约束:只接受 /plugins/ 与 /v1/plugins/ - 内核路由冲突检测:ValidateCustomMount + FindMountConflict(双向) - 鉴权默认关闭:沿用 HTTPHandler 的 roles/keys/public 语义 新增 internal/gateway/mount.go: - ValidateCustomMount:命名空间 + 冲突 + 逃逸校验,错误点名冲突对象 - FindMountConflict:**双向**检测(只查一边会让 /plugins/x 与 /plugins/x/sub 互相静默吞掉) - BuildRouteTable / RouteOwner:冲突提示点名持有者("plugin:other") - handleCustomMount:**复用** handlePluginHTTP 而不是重写一遍分发 —— 重写会造出两条必须保持一致的分发路径,而只在一处生效的安全规则 比没有更糟 关键防线:TestKernelRoutesAreAllCoveredByReservedPrefixes 从 server.go 刮出路由 switch 的字面量,逐个核对是否被 kernelReservedPrefixes 覆盖 —— 将来新增内核路由却忘记更新保留表时,这条测试会失败。否则新路由会静默 变成可被插件覆盖的。 测试 9 个:命名空间/影子内核路由/保留表同步/双向冲突/冲突点名/挂载解析/ 路由表构成/端到端(自定义挂载 200 + /v1/plugins 形式 + 未注册 404 + 无 key 401 或 302)/内核路由不可拦截。
This commit is contained in:
@ -252,6 +252,12 @@ func (g *Gateway) routes(w http.ResponseWriter, r *http.Request) {
|
||||
// Before the generic plugin router: these paths belong to a PLUGIN, not to
|
||||
// the plugin manager, and "http" is a valid sub-resource name otherwise.
|
||||
g.handlePluginHTTP(w, r)
|
||||
case strings.HasPrefix(r.URL.Path, "/plugins/") || strings.HasPrefix(r.URL.Path, "/v1/plugins/"):
|
||||
// Custom mounts a plugin or adapter claimed (R3). Checked AFTER every
|
||||
// kernel route so a claim can never shadow one — ValidateCustomMount
|
||||
// refuses the overlap at load time, and this ordering is the second line
|
||||
// of defence for a table that somehow slipped through.
|
||||
g.handleCustomMount(w, r)
|
||||
case r.URL.Path == "/api/plugins" || strings.HasPrefix(r.URL.Path, "/api/plugins/"):
|
||||
g.handlePluginsAPI(w, r)
|
||||
case r.URL.Path == "/api/chat":
|
||||
|
||||
Reference in New Issue
Block a user