551 lines
19 KiB
Go
551 lines
19 KiB
Go
package handlers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"super-frpc/config"
|
|
"super-frpc/database"
|
|
"super-frpc/postLog"
|
|
"super-frpc/utils"
|
|
|
|
"github.com/BurntSushi/toml"
|
|
)
|
|
|
|
func CreateProxyHandler(w http.ResponseWriter, r *http.Request) {
|
|
_, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
|
|
postLog.Warning(fmt.Sprintf("[CreateProxyHandler] Auth failed: %v", err))
|
|
return
|
|
}
|
|
|
|
body, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to read request body: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
|
return
|
|
}
|
|
defer r.Body.Close()
|
|
|
|
var reqMap map[string]interface{}
|
|
if err := json.Unmarshal(body, &reqMap); err != nil {
|
|
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to unmarshal request body: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
|
|
return
|
|
}
|
|
|
|
instanceID := getStringFromMap(reqMap, "instanceID")
|
|
if instanceID == "" {
|
|
postLog.Error("[CreateProxyHandler] instanceID is required")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
|
|
return
|
|
}
|
|
|
|
proxyInfoMap, ok := reqMap["proxyInfo"].(map[string]interface{})
|
|
if !ok {
|
|
postLog.Error("[CreateProxyHandler] Invalid proxyInfo format")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid proxyInfo format")
|
|
return
|
|
}
|
|
|
|
proxyInfo := config.FrpcProxyInfo{
|
|
Name: getStringFromMap(proxyInfoMap, "name"),
|
|
Type: getStringFromMap(proxyInfoMap, "type"),
|
|
LocalIP: getStringFromMap(proxyInfoMap, "localIP"),
|
|
LocalPort: getIntFromMap(proxyInfoMap, "localPort"),
|
|
RemotePort: getIntFromMap(proxyInfoMap, "remotePort"),
|
|
}
|
|
|
|
if proxyInfo.Name == "" || proxyInfo.Type == "" || proxyInfo.LocalIP == "" ||
|
|
proxyInfo.LocalPort == 0 || proxyInfo.RemotePort == 0 {
|
|
postLog.Error("[CreateProxyHandler] Missing required fields in proxyInfo")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "Missing required fields in proxyInfo")
|
|
return
|
|
}
|
|
|
|
var instance database.FrpcInstance
|
|
instanceIDInt, _ := strconv.Atoi(instanceID)
|
|
instance, err = database.DBQueryFrpcInstanceByID(instanceIDInt)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to query instance: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
|
|
return
|
|
}
|
|
|
|
// Check if the instance belongs to the user
|
|
// if instance.UserID != userID {
|
|
// postLog.Error(fmt.Sprintf("[CreateProxyHandler] Instance not found for user %d", userID))
|
|
// utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
|
|
// return
|
|
// }
|
|
|
|
configContent, err := os.ReadFile(instance.ConfigPath)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to read config file %s: %v", instance.ConfigPath, err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
|
|
return
|
|
}
|
|
|
|
updatedContent, err := config.AddFrpcProxy(string(configContent), proxyInfo)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[CreateProxyHandler] Failed to add proxy: %v", err))
|
|
utils.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))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to write config file")
|
|
return
|
|
}
|
|
|
|
utils.SendSuccessResponse(w, "Proxy created successfully", map[string]interface{}{
|
|
"instanceID": instance.ID,
|
|
"configPath": instance.ConfigPath,
|
|
"proxyName": proxyInfo.Name,
|
|
})
|
|
postLog.Info(fmt.Sprintf("[CreateProxyHandler] Proxy %s created successfully for instance %d", proxyInfo.Name, instance.ID))
|
|
}
|
|
|
|
func ModifyProxyHandler(w http.ResponseWriter, r *http.Request) {
|
|
_, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
|
|
postLog.Warning(fmt.Sprintf("[ModifyProxyHandler] Auth failed: %v", err))
|
|
return
|
|
}
|
|
|
|
body, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Failed to read request body: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
|
return
|
|
}
|
|
defer r.Body.Close()
|
|
|
|
var reqMap map[string]interface{}
|
|
if err := json.Unmarshal(body, &reqMap); err != nil {
|
|
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Failed to unmarshal request body: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
|
|
return
|
|
}
|
|
|
|
instanceID := getStringFromMap(reqMap, "instanceID")
|
|
if instanceID == "" {
|
|
postLog.Error("[ModifyProxyHandler] instanceID is required")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
|
|
return
|
|
}
|
|
|
|
proxyInfoMap, ok := reqMap["proxyInfo"].(map[string]interface{})
|
|
if !ok {
|
|
postLog.Error("[ModifyProxyHandler] Invalid proxyInfo format")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid proxyInfo format")
|
|
return
|
|
}
|
|
|
|
proxyInfo := config.FrpcProxyInfo{
|
|
OldName: getStringFromMap(proxyInfoMap, "oldName"),
|
|
NewName: getStringFromMap(proxyInfoMap, "newName"),
|
|
Name: getStringFromMap(proxyInfoMap, "name"),
|
|
Type: getStringFromMap(proxyInfoMap, "type"),
|
|
LocalIP: getStringFromMap(proxyInfoMap, "localIP"),
|
|
LocalPort: getIntFromMap(proxyInfoMap, "localPort"),
|
|
RemotePort: getIntFromMap(proxyInfoMap, "remotePort"),
|
|
}
|
|
|
|
if proxyInfo.OldName == "" {
|
|
postLog.Error("[ModifyProxyHandler] oldName is required")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "oldName is required")
|
|
return
|
|
}
|
|
|
|
if proxyInfo.NewName == "" || proxyInfo.Type == "" || proxyInfo.LocalIP == "" ||
|
|
proxyInfo.LocalPort == 0 || proxyInfo.RemotePort == 0 {
|
|
postLog.Error("[ModifyProxyHandler] Missing required fields in proxyInfo")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "Missing required fields in proxyInfo")
|
|
return
|
|
}
|
|
|
|
var instance database.FrpcInstance
|
|
instanceIDInt, _ := strconv.Atoi(instanceID)
|
|
instance, err = database.DBQueryFrpcInstanceByID(instanceIDInt)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Failed to query instance: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
|
|
return
|
|
}
|
|
|
|
// Check if the instance belongs to the user
|
|
// if instance.UserID != userID {
|
|
// postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Instance not found for user %d", userID))
|
|
// utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
|
|
// return
|
|
// }
|
|
|
|
configContent, err := os.ReadFile(instance.ConfigPath)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Failed to read config file %s: %v", instance.ConfigPath, err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
|
|
return
|
|
}
|
|
|
|
updatedContent, err := config.ModifyFrpcProxy(string(configContent), proxyInfo)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Failed to modify proxy: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to modify proxy")
|
|
return
|
|
}
|
|
|
|
if err := os.WriteFile(instance.ConfigPath, []byte(updatedContent), 0644); err != nil {
|
|
postLog.Error(fmt.Sprintf("[ModifyProxyHandler] Failed to write config file %s: %v", instance.ConfigPath, err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to write config file")
|
|
return
|
|
}
|
|
|
|
utils.SendSuccessResponse(w, "Proxy modified successfully", map[string]interface{}{
|
|
"instanceID": instance.ID,
|
|
"configPath": instance.ConfigPath,
|
|
"proxyName": proxyInfo.NewName,
|
|
})
|
|
postLog.Info(fmt.Sprintf("[ModifyProxyHandler] Proxy %s modified successfully for instance %d", proxyInfo.NewName, instance.ID))
|
|
}
|
|
|
|
func DeleteProxyHandler(w http.ResponseWriter, r *http.Request) {
|
|
_, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
|
|
postLog.Warning(fmt.Sprintf("[DeleteProxyHandler] Auth failed: %v", err))
|
|
return
|
|
}
|
|
|
|
body, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to read request body: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
|
return
|
|
}
|
|
defer r.Body.Close()
|
|
|
|
var reqMap map[string]interface{}
|
|
if err := json.Unmarshal(body, &reqMap); err != nil {
|
|
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to unmarshal request body: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
|
|
return
|
|
}
|
|
|
|
instanceID := getStringFromMap(reqMap, "instanceID")
|
|
if instanceID == "" {
|
|
postLog.Error("[DeleteProxyHandler] instanceID is required")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
|
|
return
|
|
}
|
|
|
|
proxyName := getStringFromMap(reqMap, "proxyName")
|
|
if proxyName == "" {
|
|
postLog.Error("[DeleteProxyHandler] proxyName is required")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "proxyName is required")
|
|
return
|
|
}
|
|
|
|
var instance database.FrpcInstance
|
|
instanceIDInt, _ := strconv.Atoi(instanceID)
|
|
instance, err = database.DBQueryFrpcInstanceByID(instanceIDInt)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to query instance: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
|
|
return
|
|
}
|
|
|
|
// Check if the instance belongs to the user
|
|
// if instance.UserID != userID {
|
|
// postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Instance not found for user %d", userID))
|
|
// utils.SendErrorResponse(w, http.StatusNotFound, "Instance not found")
|
|
// return
|
|
// }
|
|
|
|
configContent, err := os.ReadFile(instance.ConfigPath)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to read config file %s: %v", instance.ConfigPath, err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
|
|
return
|
|
}
|
|
|
|
updatedContent, err := config.RemoveFrpcProxy(string(configContent), proxyName)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[DeleteProxyHandler] Failed to remove proxy: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to remove proxy")
|
|
return
|
|
}
|
|
|
|
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))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to write config file")
|
|
return
|
|
}
|
|
|
|
utils.SendSuccessResponse(w, "Proxy deleted successfully", map[string]interface{}{
|
|
"instanceID": instance.ID,
|
|
"configPath": instance.ConfigPath,
|
|
"proxyName": proxyName,
|
|
})
|
|
postLog.Info(fmt.Sprintf("[DeleteProxyHandler] Proxy %s deleted successfully from instance %d", proxyName, instance.ID))
|
|
}
|
|
|
|
func ListProxiesHandler(w http.ResponseWriter, r *http.Request) {
|
|
_, err := utils.Auth(w, r, http.MethodGet)
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
|
|
postLog.Warning(fmt.Sprintf("[ListProxiesHandler] Auth failed: %v", err))
|
|
return
|
|
}
|
|
|
|
queryParams := r.URL.Query()
|
|
instanceID := queryParams.Get("instanceID")
|
|
if instanceID == "" {
|
|
postLog.Error("[ListProxiesHandler] instanceID is required")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
|
|
return
|
|
}
|
|
|
|
var instance database.FrpcInstance
|
|
instanceIDInt, _ := strconv.Atoi(instanceID)
|
|
instance, err = database.DBQueryFrpcInstanceByID(instanceIDInt)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[ListProxiesHandler] Failed to query instance: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
|
|
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))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
|
|
return
|
|
}
|
|
|
|
var cfg config.FrpcConfig
|
|
if _, err := toml.Decode(string(configContent), &cfg); err != nil {
|
|
postLog.Error(fmt.Sprintf("[ListProxiesHandler] Failed to parse config: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to parse config file")
|
|
return
|
|
}
|
|
|
|
contentStr := string(configContent)
|
|
proxyList := make([]map[string]interface{}, 0, len(cfg.Proxies))
|
|
for _, proxy := range cfg.Proxies {
|
|
proxyData := map[string]interface{}{
|
|
"name": proxy["name"],
|
|
"type": proxy["type"],
|
|
"localIP": proxy["localIP"],
|
|
"localPort": proxy["localPort"],
|
|
"remotePort": proxy["remotePort"],
|
|
"enabled": true,
|
|
}
|
|
proxyList = append(proxyList, proxyData)
|
|
}
|
|
|
|
disabledProxies := parseDisabledProxies(strings.Split(contentStr, "\n"))
|
|
proxyList = append(proxyList, disabledProxies...)
|
|
|
|
utils.SendSuccessResponse(w, "Proxies listed successfully", map[string]interface{}{
|
|
"instanceID": instance.ID,
|
|
"proxyCount": len(proxyList),
|
|
"proxies": proxyList,
|
|
})
|
|
postLog.Info(fmt.Sprintf("[ListProxiesHandler] Retrieved %d proxies for instance %d", len(proxyList), instance.ID))
|
|
}
|
|
|
|
func SwitchProxyHandler(w http.ResponseWriter, r *http.Request) {
|
|
_, err := utils.Auth(w, r, http.MethodPost, "superuser", "admin")
|
|
if err != nil {
|
|
utils.SendErrorResponse(w, http.StatusUnauthorized, err.Error())
|
|
postLog.Warning(fmt.Sprintf("[SwitchProxyHandler] Auth failed: %v", err))
|
|
return
|
|
}
|
|
|
|
body, err := io.ReadAll(r.Body)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[SwitchProxyHandler] Failed to read request body: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "Failed to read request body")
|
|
return
|
|
}
|
|
defer r.Body.Close()
|
|
|
|
var reqMap map[string]interface{}
|
|
if err := json.Unmarshal(body, &reqMap); err != nil {
|
|
postLog.Error(fmt.Sprintf("[SwitchProxyHandler] Failed to unmarshal request body: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "Invalid request format")
|
|
return
|
|
}
|
|
|
|
instanceID := getIntFromMap(reqMap, "instanceID")
|
|
if instanceID == 0 {
|
|
postLog.Error("[SwitchProxyHandler] instanceID is required")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "instanceID is required")
|
|
return
|
|
}
|
|
|
|
proxyName := getStringFromMap(reqMap, "proxyName")
|
|
if proxyName == "" {
|
|
postLog.Error("[SwitchProxyHandler] proxyName is required")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "proxyName is required")
|
|
return
|
|
}
|
|
|
|
action := getIntFromMap(reqMap, "action")
|
|
if action != 0 && action != 1 {
|
|
postLog.Error("[SwitchProxyHandler] action must be 0 or 1")
|
|
utils.SendErrorResponse(w, http.StatusBadRequest, "action must be 0 (disable) or 1 (enable)")
|
|
return
|
|
}
|
|
|
|
var instance database.FrpcInstance
|
|
instance, err = database.DBQueryFrpcInstanceByID(instanceID)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[SwitchProxyHandler] Failed to query instance: %v", err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to query instance")
|
|
return
|
|
}
|
|
|
|
configContent, err := os.ReadFile(instance.ConfigPath)
|
|
if err != nil {
|
|
postLog.Error(fmt.Sprintf("[SwitchProxyHandler] Failed to read config file %s: %v", instance.ConfigPath, err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to read config file")
|
|
return
|
|
}
|
|
|
|
lines := strings.Split(string(configContent), "\n")
|
|
startLine, endLine := findProxyBlock(lines, proxyName)
|
|
if startLine < 0 {
|
|
postLog.Error(fmt.Sprintf("[SwitchProxyHandler] Proxy %s not found in config", proxyName))
|
|
utils.SendErrorResponse(w, http.StatusNotFound, "Proxy not found in config")
|
|
return
|
|
}
|
|
|
|
if action == 0 {
|
|
for i := startLine; i <= endLine; i++ {
|
|
if !strings.HasPrefix(lines[i], "#") {
|
|
lines[i] = "#" + lines[i]
|
|
}
|
|
}
|
|
} else {
|
|
for i := startLine; i <= endLine; i++ {
|
|
lines[i] = strings.TrimPrefix(lines[i], "#")
|
|
}
|
|
}
|
|
|
|
updatedContent := strings.Join(lines, "\n")
|
|
if err := os.WriteFile(instance.ConfigPath, []byte(updatedContent), 0644); err != nil {
|
|
postLog.Error(fmt.Sprintf("[SwitchProxyHandler] Failed to write config file %s: %v", instance.ConfigPath, err))
|
|
utils.SendErrorResponse(w, http.StatusInternalServerError, "Failed to write config file")
|
|
return
|
|
}
|
|
|
|
statusText := "off"
|
|
if action == 1 {
|
|
statusText = "on"
|
|
}
|
|
utils.SendSuccessResponse(w, "Proxy status has been switched to "+statusText+".", map[string]interface{}{
|
|
"instanceID": instance.ID,
|
|
"proxyName": proxyName,
|
|
"status": statusText,
|
|
})
|
|
postLog.Info(fmt.Sprintf("[SwitchProxyHandler] Proxy %s switched %s for instance %d", proxyName, statusText, instance.ID))
|
|
}
|
|
|
|
func findProxyBlock(lines []string, proxyName string) (int, int) {
|
|
targetLine := -1
|
|
for i, line := range lines {
|
|
trimmed := strings.TrimSpace(line)
|
|
uncommented := strings.TrimPrefix(trimmed, "#")
|
|
uncommented = strings.TrimSpace(uncommented)
|
|
if strings.HasPrefix(uncommented, "name ") && strings.Contains(uncommented, proxyName) {
|
|
targetLine = i
|
|
break
|
|
}
|
|
}
|
|
|
|
if targetLine < 0 {
|
|
return -1, -1
|
|
}
|
|
|
|
startLine := targetLine
|
|
for i := targetLine; i >= 0; i-- {
|
|
trimmed := strings.TrimSpace(lines[i])
|
|
uncommented := strings.TrimPrefix(trimmed, "#")
|
|
uncommented = strings.TrimSpace(uncommented)
|
|
if uncommented == "[[proxies]]" {
|
|
startLine = i
|
|
break
|
|
}
|
|
}
|
|
|
|
endLine := targetLine
|
|
for i := targetLine + 1; i < len(lines); i++ {
|
|
trimmed := strings.TrimSpace(lines[i])
|
|
uncommented := strings.TrimPrefix(trimmed, "#")
|
|
uncommented = strings.TrimSpace(uncommented)
|
|
if uncommented == "[[proxies]]" {
|
|
endLine = i - 1
|
|
break
|
|
}
|
|
endLine = i
|
|
}
|
|
|
|
return startLine, endLine
|
|
}
|
|
|
|
func parseDisabledProxies(lines []string) []map[string]interface{} {
|
|
var disabled []map[string]interface{}
|
|
|
|
for i := 0; i < len(lines); i++ {
|
|
trimmed := strings.TrimSpace(lines[i])
|
|
if trimmed != "#[[proxies]]" {
|
|
continue
|
|
}
|
|
|
|
proxy := map[string]interface{}{"enabled": false}
|
|
for j := i + 1; j < len(lines); j++ {
|
|
line := lines[j]
|
|
if !strings.HasPrefix(strings.TrimSpace(line), "#") {
|
|
break
|
|
}
|
|
uncommented := strings.TrimPrefix(strings.TrimSpace(line), "#")
|
|
uncommented = strings.TrimSpace(uncommented)
|
|
if uncommented == "" || strings.HasPrefix(uncommented, "[[") {
|
|
break
|
|
}
|
|
parts := strings.SplitN(uncommented, "=", 2)
|
|
if len(parts) != 2 {
|
|
continue
|
|
}
|
|
key := strings.TrimSpace(parts[0])
|
|
val := strings.TrimSpace(parts[1])
|
|
proxy[key] = parseTOMLValue(val)
|
|
}
|
|
|
|
if proxy["name"] != nil && proxy["name"] != "" {
|
|
disabled = append(disabled, proxy)
|
|
}
|
|
}
|
|
|
|
return disabled
|
|
}
|
|
|
|
func parseTOMLValue(val string) interface{} {
|
|
if len(val) >= 2 && val[0] == '"' && val[len(val)-1] == '"' {
|
|
return val[1 : len(val)-1]
|
|
}
|
|
if n, err := strconv.Atoi(val); err == nil {
|
|
return n
|
|
}
|
|
return val
|
|
}
|