forked from Mxmilu666/frp
Compare commits
3 Commits
a76ecfe76c
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f5e1f7945 | ||
|
|
22ae8166d3 | ||
|
|
af6bc6369d |
16
README.md
16
README.md
@@ -13,15 +13,13 @@ frp is an open source project with its ongoing development made possible entirel
|
|||||||
|
|
||||||
<h3 align="center">Gold Sponsors</h3>
|
<h3 align="center">Gold Sponsors</h3>
|
||||||
<!--gold sponsors start-->
|
<!--gold sponsors start-->
|
||||||
<div align="center">
|
<p align="center">
|
||||||
|
<a href="https://www.recall.ai/?utm_source=github&utm_medium=sponsorship&utm_campaign=fatedier-frp" target="_blank">
|
||||||
## Recall.ai - API for meeting recordings
|
<b>Recall.ai - API for meeting recordings</b><br>
|
||||||
|
<br>
|
||||||
If you're looking for a meeting recording API, consider checking out [Recall.ai](https://www.recall.ai/?utm_source=github&utm_medium=sponsorship&utm_campaign=fatedier-frp),
|
<sup>If you're looking for a meeting recording API, consider checking out Recall.ai, an API that records Zoom, Google Meet, Microsoft Teams, in-person meetings, and more.</sup>
|
||||||
|
</a>
|
||||||
an API that records Zoom, Google Meet, Microsoft Teams, in-person meetings, and more.
|
</p>
|
||||||
|
|
||||||
</div>
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://go.warp.dev/frp" target="_blank">
|
<a href="https://go.warp.dev/frp" target="_blank">
|
||||||
<img width="360px" src="https://raw.githubusercontent.com/warpdotdev/brand-assets/refs/heads/main/Github/Sponsor/Warp-Github-LG-01.png">
|
<img width="360px" src="https://raw.githubusercontent.com/warpdotdev/brand-assets/refs/heads/main/Github/Sponsor/Warp-Github-LG-01.png">
|
||||||
|
|||||||
16
README_zh.md
16
README_zh.md
@@ -15,15 +15,13 @@ frp 是一个完全开源的项目,我们的开发工作完全依靠赞助者
|
|||||||
|
|
||||||
<h3 align="center">Gold Sponsors</h3>
|
<h3 align="center">Gold Sponsors</h3>
|
||||||
<!--gold sponsors start-->
|
<!--gold sponsors start-->
|
||||||
<div align="center">
|
<p align="center">
|
||||||
|
<a href="https://www.recall.ai/?utm_source=github&utm_medium=sponsorship&utm_campaign=fatedier-frp" target="_blank">
|
||||||
## Recall.ai - API for meeting recordings
|
<b>Recall.ai - API for meeting recordings</b><br>
|
||||||
|
<br>
|
||||||
If you're looking for a meeting recording API, consider checking out [Recall.ai](https://www.recall.ai/?utm_source=github&utm_medium=sponsorship&utm_campaign=fatedier-frp),
|
<sup>If you're looking for a meeting recording API, consider checking out Recall.ai, an API that records Zoom, Google Meet, Microsoft Teams, in-person meetings, and more.</sup>
|
||||||
|
</a>
|
||||||
an API that records Zoom, Google Meet, Microsoft Teams, in-person meetings, and more.
|
</p>
|
||||||
|
|
||||||
</div>
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://go.warp.dev/frp" target="_blank">
|
<a href="https://go.warp.dev/frp" target="_blank">
|
||||||
<img width="360px" src="https://raw.githubusercontent.com/warpdotdev/brand-assets/refs/heads/main/Github/Sponsor/Warp-Github-LG-01.png">
|
<img width="360px" src="https://raw.githubusercontent.com/warpdotdev/brand-assets/refs/heads/main/Github/Sponsor/Warp-Github-LG-01.png">
|
||||||
|
|||||||
@@ -206,9 +206,8 @@ func (m *serverMetrics) GetProxiesByType(proxyType string) []*ProxyStats {
|
|||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
|
|
||||||
filterAll := proxyType == "" || proxyType == "all"
|
|
||||||
for name, proxyStats := range m.info.ProxyStatistics {
|
for name, proxyStats := range m.info.ProxyStatistics {
|
||||||
if !filterAll && proxyStats.ProxyType != proxyType {
|
if proxyStats.ProxyType != proxyType {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,9 +233,8 @@ func (m *serverMetrics) GetProxiesByTypeAndName(proxyType string, proxyName stri
|
|||||||
m.mu.Lock()
|
m.mu.Lock()
|
||||||
defer m.mu.Unlock()
|
defer m.mu.Unlock()
|
||||||
|
|
||||||
filterAll := proxyType == "" || proxyType == "all"
|
|
||||||
for name, proxyStats := range m.info.ProxyStatistics {
|
for name, proxyStats := range m.info.ProxyStatistics {
|
||||||
if !filterAll && proxyStats.ProxyType != proxyType {
|
if proxyStats.ProxyType != proxyType {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
package version
|
package version
|
||||||
|
|
||||||
var version = "LoliaFRP 0.65.0"
|
var version = "0.65.0"
|
||||||
|
|
||||||
func Full() string {
|
func Full() string {
|
||||||
return version
|
return version
|
||||||
|
|||||||
@@ -94,28 +94,6 @@ func (cm *ControlManager) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
|
||||||
func (cm *ControlManager) KickByProxyName(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()
|
|
||||||
}
|
|
||||||
|
|
||||||
type Control struct {
|
type Control struct {
|
||||||
// all resource managers and controllers
|
// all resource managers and controllers
|
||||||
rc *controller.ResourceController
|
rc *controller.ResourceController
|
||||||
|
|||||||
@@ -52,10 +52,8 @@ 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}/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")
|
||||||
subRouter.HandleFunc("/api/proxies", svr.apiProxiesAll).Methods("GET")
|
|
||||||
|
|
||||||
// view
|
// view
|
||||||
subRouter.Handle("/favicon.ico", http.FileServer(helper.AssetsFS)).Methods("GET")
|
subRouter.Handle("/favicon.ico", http.FileServer(helper.AssetsFS)).Methods("GET")
|
||||||
@@ -213,29 +211,6 @@ type GetProxyInfoResp struct {
|
|||||||
Proxies []*ProxyStatsInfo `json:"proxies"`
|
Proxies []*ProxyStatsInfo `json:"proxies"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET /api/proxies
|
|
||||||
// Return all proxies across types (tcp, udp, http, https, stcp, xtcp, tcpmux)
|
|
||||||
func (svr *Service) apiProxiesAll(w http.ResponseWriter, r *http.Request) {
|
|
||||||
res := GeneralResponse{Code: 200}
|
|
||||||
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)
|
|
||||||
|
|
||||||
proxyInfoResp := GetProxyInfoResp{}
|
|
||||||
proxyInfoResp.Proxies = svr.getProxyStatsByType("all")
|
|
||||||
slices.SortFunc(proxyInfoResp.Proxies, func(a, b *ProxyStatsInfo) int {
|
|
||||||
return cmp.Compare(a.Name, b.Name)
|
|
||||||
})
|
|
||||||
|
|
||||||
buf, _ := json.Marshal(&proxyInfoResp)
|
|
||||||
res.Msg = string(buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// /api/proxy/:type
|
// /api/proxy/:type
|
||||||
func (svr *Service) apiProxyByType(w http.ResponseWriter, r *http.Request) {
|
func (svr *Service) apiProxyByType(w http.ResponseWriter, r *http.Request) {
|
||||||
res := GeneralResponse{Code: 200}
|
res := GeneralResponse{Code: 200}
|
||||||
@@ -262,7 +237,6 @@ func (svr *Service) apiProxyByType(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (svr *Service) getProxyStatsByType(proxyType string) (proxyInfos []*ProxyStatsInfo) {
|
func (svr *Service) getProxyStatsByType(proxyType string) (proxyInfos []*ProxyStatsInfo) {
|
||||||
// mem.StatsCollector now supports proxyType=="all" or "" to return all proxies
|
|
||||||
proxyStats := mem.StatsCollector.GetProxiesByType(proxyType)
|
proxyStats := mem.StatsCollector.GetProxiesByType(proxyType)
|
||||||
proxyInfos = make([]*ProxyStatsInfo, 0, len(proxyStats))
|
proxyInfos = make([]*ProxyStatsInfo, 0, len(proxyStats))
|
||||||
for _, ps := range proxyStats {
|
for _, ps := range proxyStats {
|
||||||
@@ -334,37 +308,6 @@ func (svr *Service) apiProxyByTypeAndName(w http.ResponseWriter, r *http.Request
|
|||||||
res.Msg = string(buf)
|
res.Msg = string(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST /api/proxy/:name/kick
|
|
||||||
// Kick the client (frpc) that owns the proxy with given name.
|
|
||||||
func (svr *Service) apiKickProxyByName(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.KickByProxyName(name); err != nil {
|
|
||||||
res.Code = 404
|
|
||||||
res.Msg = err.Error()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
res.Msg = "ok"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (svr *Service) getProxyStatsByTypeAndName(proxyType string, proxyName string) (proxyInfo GetProxyStatsResp, code int, msg string) {
|
func (svr *Service) getProxyStatsByTypeAndName(proxyType string, proxyName string) (proxyInfo GetProxyStatsResp, code int, msg string) {
|
||||||
proxyInfo.Name = proxyName
|
proxyInfo.Name = proxyName
|
||||||
ps := mem.StatsCollector.GetProxiesByTypeAndName(proxyType, proxyName)
|
ps := mem.StatsCollector.GetProxiesByTypeAndName(proxyType, proxyName)
|
||||||
|
|||||||
Reference in New Issue
Block a user