feat(proxy): add endpoint to list proxy configurations

Implement new GET endpoint `/frpcAct/proxyMgr/list` to retrieve proxy configurations from frpc instance config files. Includes handler function, API documentation, and route setup. The endpoint validates user permissions, reads and parses the config file, and returns structured proxy data with instance information.
This commit is contained in:
2026-03-21 08:57:44 +08:00
parent dcd2ae9bdc
commit 40d4ccaa8a
3 changed files with 157 additions and 1 deletions
+74 -1
View File
@@ -3,13 +3,14 @@ package main
import (
"encoding/json"
"fmt"
"github.com/BurntSushi/toml"
"io"
"net/http"
"os"
"strconv"
"strings"
"super-frpc/postLog"
"github.com/BurntSushi/toml"
)
type CreateProxyRequest struct {
@@ -279,3 +280,75 @@ func removeFrpcProxy(configContent string, proxyName string) (string, error) {
return buf.String(), nil
}
func ListProxiesHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
SendErrorResponse(w, http.StatusMethodNotAllowed, "Invalid request method")
postLog.Debug(fmt.Sprintf("[ListProxiesHandler] Invalid request method: %s", r.Method))
return
}
queryParams := r.URL.Query()
instanceID := queryParams.Get("instanceID")
if instanceID == "" {
postLog.Error("[ListProxiesHandler] instanceID is required")
SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
return
}
userID, _, err := ValidateRequestWithHeader(w, r)
if err != nil {
postLog.Error(fmt.Sprintf("[ListProxiesHandler] Failed to validate request header: %v", err))
SendErrorResponse(w, http.StatusBadRequest, "Invalid request header")
return
}
var instance FrpcInstance
instanceIDInt, _ := strconv.Atoi(instanceID)
instance, err = DBQueryFrpcInstanceByID(instanceIDInt)
if err != nil {
postLog.Error(fmt.Sprintf("[ListProxiesHandler] Failed to query instance: %v", err))
SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
return
}
if instance.UserID != userID {
postLog.Error(fmt.Sprintf("[ListProxiesHandler] Instance not found for user %d", userID))
SendErrorResponse(w, http.StatusNotFound, "Instance not found")
return
}
configContent, err := os.ReadFile(instance.ConfigPath)
if err != nil {
postLog.Error(fmt.Sprintf("[ListProxiesHandler] Failed to read config file %s: %v", instance.ConfigPath, err))
SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
return
}
var config FrpcConfig
if _, err := toml.Decode(string(configContent), &config); err != nil {
postLog.Error(fmt.Sprintf("[ListProxiesHandler] Failed to parse config: %v", err))
SendErrorResponse(w, http.StatusInternalServerError, "Failed to parse config file")
return
}
proxyList := make([]map[string]interface{}, len(config.Proxies))
for i, proxy := range config.Proxies {
proxyData := map[string]interface{}{
"name": proxy["name"],
"type": proxy["type"],
"localIP": proxy["localIP"],
"localPort": proxy["localPort"],
"remotePort": proxy["remotePort"],
}
proxyList[i] = proxyData
}
SendSuccessResponse(w, "Proxies listed successfully", map[string]interface{}{
"instanceID": instance.ID,
"instanceName": instance.Name,
"proxyCount": len(proxyList),
"proxies": proxyList,
})
postLog.Info(fmt.Sprintf("[ListProxiesHandler] Retrieved %d proxies for instance %s", len(proxyList), instance.Name))
}