refactor(frpc): replace ini with toml for config handling and improve proxy management

- Replace ini package with toml for more reliable config parsing
- Refactor proxy management to use structured config instead of string manipulation
- Add proper error handling for config operations
- Clean up unused imports and improve code organization
- Update go.mod dependencies accordingly
This commit is contained in:
2026-03-19 22:40:12 +08:00
parent c7fc0136b0
commit ab2e0567a9
8 changed files with 232 additions and 224 deletions
+62 -33
View File
@@ -3,6 +3,7 @@ package main
import (
"encoding/json"
"fmt"
"github.com/BurntSushi/toml"
"io"
"net/http"
"os"
@@ -106,8 +107,12 @@ func CreateProxyHandler(w http.ResponseWriter, r *http.Request) {
return
}
proxyConfig := addFrpcProxy(proxyInfo)
updatedContent := string(configContent) + proxyConfig
updatedContent, err := addFrpcProxy(string(configContent), proxyInfo)
if err != nil {
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to add proxy: %v", err))
SendErrorResponse(w, http.StatusInternalServerError, "Failed to add proxy")
return
}
if err := os.WriteFile(instance.ConfigPath, []byte(updatedContent), 0644); err != nil {
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to write config file %s: %v", instance.ConfigPath, err))
@@ -124,16 +129,28 @@ func CreateProxyHandler(w http.ResponseWriter, r *http.Request) {
postLog.Info(fmt.Sprintf("[CreateProxyHandler] Proxy %s created successfully for instance %s", proxyInfo.Name, instance.Name))
}
func addFrpcProxy(info FrpcProxyInfo) string {
var sb strings.Builder
sb.WriteString("\n[[proxies]]\n")
sb.WriteString(fmt.Sprintf("name = %s\n", info.Name))
sb.WriteString(fmt.Sprintf("type = %s\n", info.Type))
sb.WriteString(fmt.Sprintf("local_ip = %s\n", info.LocalIP))
sb.WriteString(fmt.Sprintf("local_port = %s\n", info.LocalPort))
sb.WriteString(fmt.Sprintf("remote_port = %s\n", info.RemotePort))
func addFrpcProxy(configContent string, info FrpcProxyInfo) (string, error) {
var config FrpcConfig
if _, err := toml.Decode(configContent, &config); err != nil {
return "", fmt.Errorf("failed to parse config: %w", err)
}
return sb.String()
proxy := map[string]interface{}{
"name": info.Name,
"type": info.Type,
"local_ip": info.LocalIP,
"local_port": info.LocalPort,
"remote_port": info.RemotePort,
}
config.Proxies = append(config.Proxies, proxy)
var buf strings.Builder
if err := toml.NewEncoder(&buf).Encode(config); err != nil {
return "", fmt.Errorf("failed to write config: %w", err)
}
return buf.String(), nil
}
func DeleteProxyHandler(w http.ResponseWriter, r *http.Request) {
@@ -211,31 +228,13 @@ func DeleteProxyHandler(w http.ResponseWriter, r *http.Request) {
return
}
lines := strings.Split(string(configContent), "\n")
var newLines []string
var i int
for i < len(lines) {
if strings.HasPrefix(lines[i], "[[proxies]]") {
nameLine := i + 1
if nameLine < len(lines) && strings.HasPrefix(lines[nameLine], "name = ") {
currentProxyName := strings.TrimSpace(strings.TrimPrefix(lines[nameLine], "name = "))
if currentProxyName == proxyName {
i += 6
continue
}
}
}
newLines = append(newLines, lines[i])
i++
}
if len(newLines) == len(lines) {
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Proxy %s not found in config file %s", proxyName, instance.ConfigPath))
SendErrorResponse(w, http.StatusNotFound, "Proxy not found")
updatedContent, err := removeFrpcProxy(string(configContent), proxyName)
if err != nil {
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to remove proxy: %v", err))
SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove proxy")
return
}
updatedContent := strings.Join(newLines, "\n")
if err := os.WriteFile(instance.ConfigPath, []byte(updatedContent), 0644); err != nil {
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to write config file %s: %v", instance.ConfigPath, err))
SendErrorResponse(w, http.StatusInternalServerError, "Failed to write config file")
@@ -250,3 +249,33 @@ func DeleteProxyHandler(w http.ResponseWriter, r *http.Request) {
})
postLog.Info(fmt.Sprintf("[DeleteProxyHandler] Proxy %s deleted successfully from instance %s", proxyName, instance.Name))
}
func removeFrpcProxy(configContent string, proxyName string) (string, error) {
var config FrpcConfig
if _, err := toml.Decode(configContent, &config); err != nil {
return "", fmt.Errorf("failed to parse config: %w", err)
}
var found bool
var newProxies []map[string]interface{}
for _, proxy := range config.Proxies {
if name, ok := proxy["name"].(string); ok && name == proxyName {
found = true
continue
}
newProxies = append(newProxies, proxy)
}
if !found {
return "", fmt.Errorf("proxy %s not found", proxyName)
}
config.Proxies = newProxies
var buf strings.Builder
if err := toml.NewEncoder(&buf).Encode(config); err != nil {
return "", fmt.Errorf("failed to write config: %w", err)
}
return buf.String(), nil
}