package rule import ( "fmt" "net" "net/http" "regexp" "strings" ) // Match DNS规则匹配 func (r *DNSRule) Match(req *http.Request) bool { host := req.Host if strings.Contains(host, ":") { host, _, _ = net.SplitHostPort(host) } switch r.MatchType { case MatchTypeExact: return host == r.Pattern case MatchTypeWildcard: return matchWildcard(host, r.Pattern) case MatchTypeRegex: if re, err := regexp.Compile(r.Pattern); err == nil { return re.MatchString(host) } } return false } // Apply DNS规则应用 func (r *DNSRule) Apply(req *http.Request) error { if !r.Enabled { return nil } // DNS规则的应用在DNS解析阶段处理,这里不需要修改请求 return nil } // Validate DNS规则验证 func (r *DNSRule) Validate() error { if r.ID == "" { return fmt.Errorf("规则ID不能为空") } if len(r.Targets) == 0 { return fmt.Errorf("DNS规则必须包含至少一个目标") } for _, target := range r.Targets { if net.ParseIP(target.IP) == nil { return fmt.Errorf("无效的IP地址: %s", target.IP) } if target.Port < 0 || target.Port > 65535 { return fmt.Errorf("无效的端口号: %d", target.Port) } } return nil } // Match URL重写规则匹配 func (r *RewriteRule) Match(req *http.Request) bool { switch r.MatchType { case MatchTypeExact: return req.URL.Path == r.Pattern case MatchTypePath: return strings.HasPrefix(req.URL.Path, r.Pattern) case MatchTypeRegex: if re, err := regexp.Compile(r.Pattern); err == nil { return re.MatchString(req.URL.Path) } } return false } // Apply URL重写规则应用 func (r *RewriteRule) Apply(req *http.Request) error { if !r.Enabled { return nil } switch r.MatchType { case MatchTypeExact, MatchTypePath: req.URL.Path = strings.Replace(req.URL.Path, r.Pattern, r.Replacement, 1) case MatchTypeRegex: if re, err := regexp.Compile(r.Pattern); err == nil { req.URL.Path = re.ReplaceAllString(req.URL.Path, r.Replacement) } else { return fmt.Errorf("正则表达式编译失败: %v", err) } } return nil } // Validate URL重写规则验证 func (r *RewriteRule) Validate() error { if r.ID == "" { return fmt.Errorf("规则ID不能为空") } if r.Pattern == "" { return fmt.Errorf("重写规则必须包含匹配模式") } if r.MatchType == MatchTypeRegex { if _, err := regexp.Compile(r.Pattern); err != nil { return fmt.Errorf("无效的正则表达式: %v", err) } } return nil } // Match 路由规则匹配 func (r *RouteRule) Match(req *http.Request) bool { switch r.MatchType { case MatchTypeExact: return req.URL.Path == r.Pattern case MatchTypePath: return strings.HasPrefix(req.URL.Path, r.Pattern) case MatchTypeRegex: if re, err := regexp.Compile(r.Pattern); err == nil { return re.MatchString(req.URL.Path) } } return false } // Apply 路由规则应用 func (r *RouteRule) Apply(req *http.Request) error { if !r.Enabled { return nil } // 修改请求头 for key, value := range r.HeaderModifier { // 支持变量替换 switch value { case "${client_ip}": clientIP := req.RemoteAddr if ip, _, err := net.SplitHostPort(clientIP); err == nil { req.Header.Set(key, ip) } else { req.Header.Set(key, clientIP) } default: req.Header.Set(key, value) } } return nil } // Validate 路由规则验证 func (r *RouteRule) Validate() error { if r.ID == "" { return fmt.Errorf("规则ID不能为空") } if r.Pattern == "" { return fmt.Errorf("路由规则必须包含匹配模式") } if r.Target == "" { return fmt.Errorf("路由规则必须包含目标地址") } if r.MatchType == MatchTypeRegex { if _, err := regexp.Compile(r.Pattern); err != nil { return fmt.Errorf("无效的正则表达式: %v", err) } } return nil } // 辅助函数:通配符匹配 func matchWildcard(host, pattern string) bool { if !strings.Contains(pattern, "*") { return host == pattern } parts := strings.Split(pattern, ".") hostParts := strings.Split(host, ".") if len(parts) != len(hostParts) { return false } for i := 0; i < len(parts); i++ { if parts[i] != "*" && parts[i] != hostParts[i] { return false } } return true }