From bb11c5afc6783d137201c0a1ff415ba77a08de31 Mon Sep 17 00:00:00 2001 From: Darien Raymond <admin@v2ray.com> Date: Sat, 1 Dec 2018 21:06:45 +0100 Subject: [PATCH] support domain property --- main.go | 90 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 19 deletions(-) diff --git a/main.go b/main.go index ad709033..acc3ca4b 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "os" "path/filepath" + "strconv" "strings" "github.com/gogo/protobuf/proto" @@ -16,6 +17,7 @@ import ( type Entry struct { Type string Value string + Attrs []*router.Domain_Attribute } type List struct { @@ -37,23 +39,27 @@ func (l *ParsedList) toProto() (*router.GeoSite, error) { switch entry.Type { case "domain": site.Domain = append(site.Domain, &router.Domain{ - Type: router.Domain_Domain, - Value: entry.Value, + Type: router.Domain_Domain, + Value: entry.Value, + Attribute: entry.Attrs, }) case "regex": site.Domain = append(site.Domain, &router.Domain{ - Type: router.Domain_Regex, - Value: entry.Value, + Type: router.Domain_Regex, + Value: entry.Value, + Attribute: entry.Attrs, }) case "keyword": site.Domain = append(site.Domain, &router.Domain{ - Type: router.Domain_Plain, - Value: entry.Value, + Type: router.Domain_Plain, + Value: entry.Value, + Attribute: entry.Attrs, }) case "full": site.Domain = append(site.Domain, &router.Domain{ - Type: router.Domain_Full, - Value: entry.Value, + Type: router.Domain_Full, + Value: entry.Value, + Attribute: entry.Attrs, }) default: return nil, errors.New("unknown domain type: " + entry.Type) @@ -70,21 +76,67 @@ func removeComment(line string) string { return strings.TrimSpace(line[:idx]) } -func parseEntry(line string) (Entry, error) { - kv := strings.Split(line, ":") +func parseDomain(domain string, entry *Entry) error { + kv := strings.Split(domain, ":") if len(kv) == 1 { - return Entry{ - Type: "domain", - Value: kv[0], - }, nil + entry.Type = "domain" + entry.Value = strings.ToLower(kv[0]) + return nil } + if len(kv) == 2 { - return Entry{ - Type: strings.ToLower(kv[0]), - Value: strings.ToLower(kv[1]), - }, nil + entry.Type = strings.ToLower(kv[0]) + entry.Value = strings.ToLower(kv[1]) + return nil } - return Entry{}, errors.New("Invalid format: " + line) + + return errors.New("Invalid format: " + domain) +} + +func parseAttribute(attr string) (router.Domain_Attribute, error) { + var attribute router.Domain_Attribute + if len(attr) == 0 || attr[0] != '@' { + return attribute, errors.New("invalid attribute: " + attr) + } + + attr = attr[0:] + parts := strings.Split(attr, "=") + if len(parts) == 1 { + attribute.Key = strings.ToLower(parts[0]) + attribute.TypedValue = &router.Domain_Attribute_BoolValue{BoolValue: true} + } else { + attribute.Key = strings.ToLower(parts[0]) + intv, err := strconv.Atoi(parts[1]) + if err != nil { + return attribute, errors.New("invalid attribute: " + attr + ": " + err.Error()) + } + attribute.TypedValue = &router.Domain_Attribute_IntValue{IntValue: int64(intv)} + } + return attribute, nil +} + +func parseEntry(line string) (Entry, error) { + line = strings.TrimSpace(line) + parts := strings.Split(line, " ") + + var entry Entry + if len(parts) == 0 { + return entry, errors.New("empty entry") + } + + if err := parseDomain(parts[0], &entry); err != nil { + return entry, err + } + + for i := 1; i < len(parts); i++ { + attr, err := parseAttribute(parts[i]) + if err != nil { + return entry, err + } + entry.Attrs = append(entry.Attrs, &attr) + } + + return entry, nil } func DetectPath(path string) (string, error) {