mirror of
https://github.com/fatedier/frp.git
synced 2026-05-01 05:29:10 +08:00
feat(api): add endpoint to close proxy by name
This commit is contained in:
@@ -94,8 +94,28 @@ func (cm *ControlManager) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CloseAllProxyByName Finds the tunnel name and closes all tunnels on the same connection.
|
||||||
|
func (cm *ControlManager) CloseAllProxyByName(proxyName string) error {
|
||||||
|
cm.mu.RLock()
|
||||||
|
var target *Control
|
||||||
|
for _, ctl := range cm.ctlsByRunID {
|
||||||
|
ctl.mu.RLock()
|
||||||
|
_, ok := ctl.proxies[proxyName]
|
||||||
|
ctl.mu.RUnlock()
|
||||||
|
if ok {
|
||||||
|
target = ctl
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cm.mu.RUnlock()
|
||||||
|
if target == nil {
|
||||||
|
return fmt.Errorf("no proxy found with name [%s]", proxyName)
|
||||||
|
}
|
||||||
|
return target.Close()
|
||||||
|
}
|
||||||
|
|
||||||
// KickByProxyName finds the Control that manages the given proxy (tunnel) name and closes
|
// KickByProxyName finds the Control that manages the given proxy (tunnel) name and closes
|
||||||
// the entire control connection (disconnects the frpc). Returns an error if no such proxy is found.
|
// Bug: The client does not display the kickout message.
|
||||||
func (cm *ControlManager) KickByProxyName(proxyName string) error {
|
func (cm *ControlManager) KickByProxyName(proxyName string) error {
|
||||||
cm.mu.RLock()
|
cm.mu.RLock()
|
||||||
var target *Control
|
var target *Control
|
||||||
@@ -113,6 +133,9 @@ func (cm *ControlManager) KickByProxyName(proxyName string) error {
|
|||||||
if target == nil {
|
if target == nil {
|
||||||
return fmt.Errorf("no proxy found with name [%s]", proxyName)
|
return fmt.Errorf("no proxy found with name [%s]", proxyName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xl := target.xl
|
||||||
|
xl.Infof("kick client with proxy [%s] by server administrator request", proxyName)
|
||||||
return target.Close()
|
return target.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ func (svr *Service) registerRouteHandlers(helper *httppkg.RouterRegisterHelper)
|
|||||||
subRouter.HandleFunc("/api/serverinfo", svr.apiServerInfo).Methods("GET")
|
subRouter.HandleFunc("/api/serverinfo", svr.apiServerInfo).Methods("GET")
|
||||||
subRouter.HandleFunc("/api/proxy/{type}", svr.apiProxyByType).Methods("GET")
|
subRouter.HandleFunc("/api/proxy/{type}", svr.apiProxyByType).Methods("GET")
|
||||||
subRouter.HandleFunc("/api/proxy/{type}/{name}", svr.apiProxyByTypeAndName).Methods("GET")
|
subRouter.HandleFunc("/api/proxy/{type}/{name}", svr.apiProxyByTypeAndName).Methods("GET")
|
||||||
|
subRouter.HandleFunc("/api/proxy/{name}/close", svr.apiCloseProxyByName).Methods("POST")
|
||||||
subRouter.HandleFunc("/api/proxy/{name}/kick", svr.apiKickProxyByName).Methods("POST")
|
subRouter.HandleFunc("/api/proxy/{name}/kick", svr.apiKickProxyByName).Methods("POST")
|
||||||
subRouter.HandleFunc("/api/traffic/{name}", svr.apiProxyTraffic).Methods("GET")
|
subRouter.HandleFunc("/api/traffic/{name}", svr.apiProxyTraffic).Methods("GET")
|
||||||
subRouter.HandleFunc("/api/proxies", svr.deleteProxies).Methods("DELETE")
|
subRouter.HandleFunc("/api/proxies", svr.deleteProxies).Methods("DELETE")
|
||||||
@@ -334,8 +335,40 @@ func (svr *Service) apiProxyByTypeAndName(w http.ResponseWriter, r *http.Request
|
|||||||
res.Msg = string(buf)
|
res.Msg = string(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// POST /api/proxy/:name/close
|
||||||
|
// Close the proxy with given name only. The client connection remains active.
|
||||||
|
func (svr *Service) apiCloseProxyByName(w http.ResponseWriter, r *http.Request) {
|
||||||
|
res := GeneralResponse{Code: 200}
|
||||||
|
params := mux.Vars(r)
|
||||||
|
name := params["name"]
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
log.Infof("http response [%s]: code [%d]", r.URL.Path, res.Code)
|
||||||
|
w.WriteHeader(res.Code)
|
||||||
|
if len(res.Msg) > 0 {
|
||||||
|
_, _ = w.Write([]byte(res.Msg))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
log.Infof("http request: [%s]", r.URL.Path)
|
||||||
|
|
||||||
|
if name == "" {
|
||||||
|
res.Code = 400
|
||||||
|
res.Msg = "proxy name required"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := svr.ctlManager.CloseAllProxyByName(name); err != nil {
|
||||||
|
res.Code = 404
|
||||||
|
res.Msg = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
res.Msg = "ok"
|
||||||
|
}
|
||||||
|
|
||||||
// POST /api/proxy/:name/kick
|
// POST /api/proxy/:name/kick
|
||||||
// Kick the client (frpc) that owns the proxy with given name.
|
// Kick the client (frpc) that owns the proxy with given name.
|
||||||
|
// This will disconnect the entire frpc client and close all its proxies.
|
||||||
func (svr *Service) apiKickProxyByName(w http.ResponseWriter, r *http.Request) {
|
func (svr *Service) apiKickProxyByName(w http.ResponseWriter, r *http.Request) {
|
||||||
res := GeneralResponse{Code: 200}
|
res := GeneralResponse{Code: 200}
|
||||||
params := mux.Vars(r)
|
params := mux.Vars(r)
|
||||||
|
|||||||
Reference in New Issue
Block a user