github.com/inazumav/sing-box@v0.0.0-20230926072359-ab51429a14f1/route/rule_item_domain_regex.go (about) 1 package route 2 3 import ( 4 "regexp" 5 "strings" 6 7 "github.com/inazumav/sing-box/adapter" 8 E "github.com/sagernet/sing/common/exceptions" 9 F "github.com/sagernet/sing/common/format" 10 ) 11 12 var _ RuleItem = (*DomainRegexItem)(nil) 13 14 type DomainRegexItem struct { 15 matchers []*regexp.Regexp 16 description string 17 } 18 19 func NewDomainRegexItem(expressions []string) (*DomainRegexItem, error) { 20 matchers := make([]*regexp.Regexp, 0, len(expressions)) 21 for i, regex := range expressions { 22 matcher, err := regexp.Compile(regex) 23 if err != nil { 24 return nil, E.Cause(err, "parse expression ", i) 25 } 26 matchers = append(matchers, matcher) 27 } 28 description := "domain_regex=" 29 eLen := len(expressions) 30 if eLen == 1 { 31 description += expressions[0] 32 } else if eLen > 3 { 33 description += F.ToString("[", strings.Join(expressions[:3], " "), "]") 34 } else { 35 description += F.ToString("[", strings.Join(expressions, " "), "]") 36 } 37 return &DomainRegexItem{matchers, description}, nil 38 } 39 40 func (r *DomainRegexItem) Match(metadata *adapter.InboundContext) bool { 41 var domainHost string 42 if metadata.Domain != "" { 43 domainHost = metadata.Domain 44 } else { 45 domainHost = metadata.Destination.Fqdn 46 } 47 if domainHost == "" { 48 return false 49 } 50 domainHost = strings.ToLower(domainHost) 51 for _, matcher := range r.matchers { 52 if matcher.MatchString(domainHost) { 53 return true 54 } 55 } 56 return false 57 } 58 59 func (r *DomainRegexItem) String() string { 60 return r.description 61 }