feat(controller): add API to close proxy by name

This commit is contained in:
2026-02-21 07:42:17 +08:00
parent 1f2c26761d
commit 83847f32ed
5 changed files with 66 additions and 6 deletions

View File

@@ -14,7 +14,7 @@
package version
var version = "LoliaFRP-CLI 0.67.1"
var version = "LoliaFRP-CLI 0.67.2"
func Full() string {
return version

View File

@@ -38,21 +38,28 @@ type Controller struct {
serverCfg *v1.ServerConfig
clientRegistry *registry.ClientRegistry
pxyManager ProxyManager
ctlManager ControlManager
}
type ProxyManager interface {
GetByName(name string) (proxy.Proxy, bool)
}
type ControlManager interface {
CloseAllProxyByName(proxyName string) error
}
func NewController(
serverCfg *v1.ServerConfig,
clientRegistry *registry.ClientRegistry,
pxyManager ProxyManager,
ctlManager ControlManager,
) *Controller {
return &Controller{
serverCfg: serverCfg,
clientRegistry: clientRegistry,
pxyManager: pxyManager,
ctlManager: ctlManager,
}
}
@@ -246,6 +253,24 @@ func (c *Controller) APIProxyByName(ctx *httppkg.Context) (any, error) {
return proxyInfo, nil
}
// POST /api/proxy/:name/close
func (c *Controller) APICloseProxyByName(ctx *httppkg.Context) (any, error) {
name := ctx.Param("name")
if name == "" {
return nil, httppkg.NewError(http.StatusBadRequest, "proxy name required")
}
if c.ctlManager == nil {
return nil, fmt.Errorf("control manager unavailable")
}
if err := c.ctlManager.CloseAllProxyByName(name); err != nil {
return nil, httppkg.NewError(http.StatusNotFound, err.Error())
}
return httppkg.GeneralResponse{Code: 200, Msg: "ok"}, nil
}
// DELETE /api/proxies?status=offline
func (c *Controller) DeleteProxies(ctx *httppkg.Context) (any, error) {
status := ctx.Query("status")

View File

@@ -703,12 +703,13 @@ func (svr *Service) registerRouteHandlers(helper *httppkg.RouterRegisterHelper)
subRouter.Handle("/metrics", promhttp.Handler())
}
apiController := api.NewController(svr.cfg, svr.clientRegistry, svr.pxyManager)
apiController := api.NewController(svr.cfg, svr.clientRegistry, svr.pxyManager, svr.ctlManager)
// apis
subRouter.HandleFunc("/api/serverinfo", httppkg.MakeHTTPHandlerFunc(apiController.APIServerInfo)).Methods("GET")
subRouter.HandleFunc("/api/proxy/{type}", httppkg.MakeHTTPHandlerFunc(apiController.APIProxyByType)).Methods("GET")
subRouter.HandleFunc("/api/proxy/{type}/{name}", httppkg.MakeHTTPHandlerFunc(apiController.APIProxyByTypeAndName)).Methods("GET")
subRouter.HandleFunc("/api/proxy/{name}/close", httppkg.MakeHTTPHandlerFunc(apiController.APICloseProxyByName)).Methods("POST")
subRouter.HandleFunc("/api/proxies/{name}", httppkg.MakeHTTPHandlerFunc(apiController.APIProxyByName)).Methods("GET")
subRouter.HandleFunc("/api/traffic/{name}", httppkg.MakeHTTPHandlerFunc(apiController.APIProxyTraffic)).Methods("GET")
subRouter.HandleFunc("/api/clients", httppkg.MakeHTTPHandlerFunc(apiController.APIClientList)).Methods("GET")

View File

@@ -1446,6 +1446,7 @@
"node_modules/@types/lodash-es": {
"version": "4.17.12",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/lodash": "*"
}
@@ -1454,6 +1455,7 @@
"version": "24.10.4",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~7.16.0"
}
@@ -1506,6 +1508,7 @@
"version": "6.20.0",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "6.20.0",
"@typescript-eslint/types": "6.20.0",
@@ -1906,6 +1909,7 @@
"version": "14.1.0",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/web-bluetooth": "^0.0.21",
"@vueuse/metadata": "14.1.0",
@@ -1941,6 +1945,7 @@
"version": "8.15.0",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -2789,6 +2794,7 @@
"version": "8.56.0",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -2843,6 +2849,7 @@
"version": "9.1.0",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"eslint-config-prettier": "bin/cli.js"
},
@@ -2883,6 +2890,7 @@
"version": "9.33.0",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"globals": "^13.24.0",
@@ -3970,13 +3978,15 @@
"version": "4.17.23",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/lodash-es": {
"version": "4.17.23",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz",
"integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/lodash-unified": {
"version": "1.0.3",
@@ -4521,6 +4531,7 @@
"version": "3.7.4",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -4683,6 +4694,7 @@
"version": "4.55.1",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/estree": "1.0.8"
},
@@ -5074,6 +5086,7 @@
"version": "5.44.1",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.15.0",
@@ -5135,6 +5148,7 @@
"version": "4.0.3",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@@ -5210,6 +5224,7 @@
"version": "5.9.3",
"devOptional": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -5609,6 +5624,7 @@
"version": "7.3.1",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.27.0",
"fdir": "^6.5.0",
@@ -5721,6 +5737,7 @@
"version": "4.0.3",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@@ -5736,6 +5753,7 @@
"node_modules/vue": {
"version": "3.5.26",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.26",
"@vue/compiler-sfc": "3.5.26",

View File

@@ -1556,6 +1556,7 @@
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/lodash": "*"
}
@@ -1566,6 +1567,7 @@
"integrity": "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~7.16.0"
}
@@ -1626,6 +1628,7 @@
"integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "6.21.0",
"@typescript-eslint/types": "6.21.0",
@@ -2038,6 +2041,7 @@
"integrity": "sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/web-bluetooth": "^0.0.21",
"@vueuse/metadata": "14.1.0",
@@ -2079,6 +2083,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -3039,6 +3044,7 @@
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -3095,6 +3101,7 @@
"integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"eslint-config-prettier": "bin/cli.js"
},
@@ -3139,6 +3146,7 @@
"integrity": "sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
"globals": "^13.24.0",
@@ -4513,13 +4521,15 @@
"version": "4.17.23",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/lodash-es": {
"version": "4.17.23",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz",
"integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/lodash-unified": {
"version": "1.0.3",
@@ -5145,6 +5155,7 @@
"integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"prettier": "bin/prettier.cjs"
},
@@ -5354,6 +5365,7 @@
"integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/estree": "1.0.8"
},
@@ -5795,6 +5807,7 @@
"integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.15.0",
@@ -5922,6 +5935,7 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"devOptional": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -6369,6 +6383,7 @@
"integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.27.0",
"fdir": "^6.5.0",
@@ -6463,6 +6478,7 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.26.tgz",
"integrity": "sha512-SJ/NTccVyAoNUJmkM9KUqPcYlY+u8OVL1X5EW9RIs3ch5H2uERxyyIUI4MRxVCSOiEcupX9xNGde1tL9ZKpimA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.5.26",
"@vue/compiler-sfc": "3.5.26",