71 lines
1.4 KiB
Go
71 lines
1.4 KiB
Go
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)
|
|
}
|