package resolver import "strings" type WildcardMatcher struct { exact map[string]struct{} suffix []string } func NormalizeWildcardDomain(raw string) string { d := strings.TrimSpace(strings.SplitN(raw, "#", 2)[0]) d = strings.ToLower(d) d = strings.TrimPrefix(d, "*.") d = strings.TrimPrefix(d, ".") d = strings.TrimSuffix(d, ".") return d } func NewWildcardMatcher(domains []string) WildcardMatcher { seen := map[string]struct{}{} m := WildcardMatcher{exact: map[string]struct{}{}} for _, raw := range domains { d := NormalizeWildcardDomain(raw) if d == "" { continue } if _, ok := seen[d]; ok { continue } seen[d] = struct{}{} m.exact[d] = struct{}{} m.suffix = append(m.suffix, "."+d) } return m } func (m WildcardMatcher) Match(host string) bool { if len(m.exact) == 0 { return false } h := strings.TrimSuffix(strings.ToLower(strings.TrimSpace(host)), ".") if h == "" { return false } if _, ok := m.exact[h]; ok { return true } for _, suffix := range m.suffix { if strings.HasSuffix(h, suffix) { return true } } return false } func (m WildcardMatcher) IsExact(host string) bool { if len(m.exact) == 0 { return false } h := strings.TrimSuffix(strings.ToLower(strings.TrimSpace(host)), ".") if h == "" { return false } _, ok := m.exact[h] return ok } func (m WildcardMatcher) Count() int { return len(m.exact) }