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:
+82
@@ -784,6 +784,88 @@ X-Timestamp: 1704067200000
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## List Proxies
|
||||||
|
|
||||||
|
**Endpoint:** `/frpcAct/proxyMgr/list`
|
||||||
|
**Method:** GET
|
||||||
|
**Auth Required:** Yes (token)
|
||||||
|
**Permission Level:** None (any permission level)
|
||||||
|
|
||||||
|
Retrieve a list of all proxy configurations for a specific frpc instance. The proxy configurations are read from the instance's config file.
|
||||||
|
|
||||||
|
**Request Headers:**
|
||||||
|
```
|
||||||
|
X-Token: your_token
|
||||||
|
X-Timestamp: 1704067200000
|
||||||
|
```
|
||||||
|
|
||||||
|
**Query Parameters:**
|
||||||
|
```
|
||||||
|
?instanceID=1
|
||||||
|
```
|
||||||
|
|
||||||
|
| Header | Type | Required | Description |
|
||||||
|
|--------|------|----------|-------------|
|
||||||
|
| X-Token | string | Yes | Authentication token |
|
||||||
|
| X-Timestamp | int64 | Yes | Client timestamp in milliseconds |
|
||||||
|
|
||||||
|
| Parameter | Type | Required | Description |
|
||||||
|
|-----------|------|----------|-------------|
|
||||||
|
| instanceID | string | Yes | Instance ID (the ID of the frpc instance) |
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"message": "Proxies listed successfully",
|
||||||
|
"data": {
|
||||||
|
"instanceID": 1,
|
||||||
|
"instanceName": "my_frpc",
|
||||||
|
"proxyCount": 2,
|
||||||
|
"proxies": [
|
||||||
|
{
|
||||||
|
"name": "ssh_proxy",
|
||||||
|
"type": "tcp",
|
||||||
|
"local_ip": "127.0.0.1",
|
||||||
|
"local_port": "22",
|
||||||
|
"remote_port": "6000"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "web_proxy",
|
||||||
|
"type": "http",
|
||||||
|
"local_ip": "127.0.0.1",
|
||||||
|
"local_port": "8080",
|
||||||
|
"remote_port": "80"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| instanceID | int | Instance ID |
|
||||||
|
| instanceName | string | Name of the frpc instance |
|
||||||
|
| proxyCount | int | Number of proxies |
|
||||||
|
| proxies | array | List of proxy configurations |
|
||||||
|
|
||||||
|
**Proxy Object:**
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| name | string | Proxy name |
|
||||||
|
| type | string | Proxy type (e.g., tcp, udp, http, https) |
|
||||||
|
| local_ip | string | Local IP address to forward to |
|
||||||
|
| local_port | string | Local port to forward from |
|
||||||
|
| remote_port | string | Remote port on frps to expose |
|
||||||
|
|
||||||
|
> **Note:**
|
||||||
|
> - The proxy configurations are read from the existing config file
|
||||||
|
> - This endpoint does not modify the database, only reads the config file
|
||||||
|
> - The returned proxy list represents the current configuration in the file
|
||||||
|
> - Changes to the config file will be reflected in subsequent requests
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## List frpc Instances
|
## List frpc Instances
|
||||||
|
|
||||||
**Endpoint:** `/frpcAct/instanceMgr/list`
|
**Endpoint:** `/frpcAct/instanceMgr/list`
|
||||||
|
|||||||
+74
-1
@@ -3,13 +3,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/BurntSushi/toml"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"super-frpc/postLog"
|
"super-frpc/postLog"
|
||||||
|
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CreateProxyRequest struct {
|
type CreateProxyRequest struct {
|
||||||
@@ -279,3 +280,75 @@ func removeFrpcProxy(configContent string, proxyName string) (string, error) {
|
|||||||
|
|
||||||
return buf.String(), nil
|
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))
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ func setupRoutes() {
|
|||||||
http.HandleFunc("/frpcAct/instanceMgr/list", ListInstancesHandler)
|
http.HandleFunc("/frpcAct/instanceMgr/list", ListInstancesHandler)
|
||||||
http.HandleFunc("/frpcAct/proxyMgr/create", CreateProxyHandler)
|
http.HandleFunc("/frpcAct/proxyMgr/create", CreateProxyHandler)
|
||||||
http.HandleFunc("/frpcAct/proxyMgr/delete", DeleteProxyHandler)
|
http.HandleFunc("/frpcAct/proxyMgr/delete", DeleteProxyHandler)
|
||||||
|
http.HandleFunc("/frpcAct/proxyMgr/list", ListProxiesHandler)
|
||||||
|
|
||||||
http.HandleFunc("/", NotFoundHandler)
|
http.HandleFunc("/", NotFoundHandler)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user