Files
flvx/go-backend/internal/http/handler/tunnel_probe_target.go
T
2026-05-01 22:45:58 +08:00

76 lines
2.1 KiB
Go

package handler
import (
"errors"
"fmt"
"net/netip"
"strings"
"go-backend/internal/store/model"
)
const (
defaultTunnelProbeTargetHost = "www.bing.com"
defaultTunnelProbeTargetPort = 443
)
type tunnelProbeTarget struct {
Host string
Port int
}
func defaultTunnelProbeTarget() tunnelProbeTarget {
return tunnelProbeTarget{Host: defaultTunnelProbeTargetHost, Port: defaultTunnelProbeTargetPort}
}
func normalizeTunnelProbeTarget(host string, port int) (tunnelProbeTarget, bool, error) {
host = strings.TrimSpace(host)
if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
host = strings.TrimPrefix(strings.TrimSuffix(host, "]"), "[")
}
if host == "" && port == 0 {
return defaultTunnelProbeTarget(), false, nil
}
if host == "" {
return tunnelProbeTarget{}, false, errors.New("测试目标 Host 不能为空")
}
if port <= 0 || port > 65535 {
return tunnelProbeTarget{}, false, errors.New("测试目标端口必须是 1-65535")
}
if strings.Contains(host, "://") || strings.ContainsAny(host, "/?#") || strings.ContainsAny(host, " \t\r\n") {
return tunnelProbeTarget{}, false, errors.New("测试目标 Host 不能包含协议或路径")
}
return tunnelProbeTarget{Host: host, Port: port}, true, nil
}
func parseTunnelProbeTargetFromRequest(req map[string]interface{}) (tunnelProbeTarget, bool, error) {
if req == nil {
return defaultTunnelProbeTarget(), false, nil
}
return normalizeTunnelProbeTarget(asString(req["probeTargetHost"]), asInt(req["probeTargetPort"], 0))
}
func effectiveTunnelProbeTarget(tunnel *model.Tunnel) tunnelProbeTarget {
if tunnel == nil {
return defaultTunnelProbeTarget()
}
return defaultTunnelProbeTarget()
}
func effectiveTunnelProbeTargetValues(host string, port int) tunnelProbeTarget {
target, configured, err := normalizeTunnelProbeTarget(host, port)
if err != nil || !configured {
return defaultTunnelProbeTarget()
}
return target
}
func formatTunnelProbeTarget(target tunnelProbeTarget) string {
if addr, err := netip.ParseAddr(target.Host); err == nil && addr.Is6() {
return fmt.Sprintf("[%s]:%d", target.Host, target.Port)
}
return fmt.Sprintf("%s:%d", target.Host, target.Port)
}