Pull request: home: imp whois parse
Updates #2646. Squashed commit of the following: commit 0a5ff6ae74c532a296c0594a598a99c7cfaccf8c Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Thu May 20 14:07:08 2021 +0300 home: imp code commit 2af0f463a77b81e827d9faca079a19c5437e1cd9 Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Thu May 20 13:48:08 2021 +0300 home: imp whois parse
This commit is contained in:
parent
21972e49cb
commit
9c60aef637
|
@ -10,7 +10,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghio"
|
"github.com/AdguardTeam/AdGuardHome/internal/aghio"
|
||||||
"github.com/AdguardTeam/AdGuardHome/internal/aghstrings"
|
|
||||||
"github.com/AdguardTeam/golibs/cache"
|
"github.com/AdguardTeam/golibs/cache"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
)
|
)
|
||||||
|
@ -66,55 +65,71 @@ func trimValue(s string) string {
|
||||||
return s[:maxValueLength-3] + "..."
|
return s[:maxValueLength-3] + "..."
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse plain-text data from the response
|
// coalesceStr returns the first non-empty string.
|
||||||
func whoisParse(data string) map[string]string {
|
//
|
||||||
m := map[string]string{}
|
// TODO(a.garipov): Move to aghstrings?
|
||||||
descr := ""
|
func coalesceStr(strs ...string) (res string) {
|
||||||
netname := ""
|
for _, s := range strs {
|
||||||
for len(data) != 0 {
|
if s != "" {
|
||||||
ln := aghstrings.SplitNext(&data, '\n')
|
return s
|
||||||
if len(ln) == 0 || ln[0] == '#' || ln[0] == '%' {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
kv := strings.SplitN(ln, ":", 2)
|
|
||||||
if len(kv) != 2 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
k := strings.TrimSpace(kv[0])
|
|
||||||
k = strings.ToLower(k)
|
|
||||||
v := strings.TrimSpace(kv[1])
|
|
||||||
|
|
||||||
switch k {
|
|
||||||
case "org-name":
|
|
||||||
m["orgname"] = trimValue(v)
|
|
||||||
case "city", "country", "orgname":
|
|
||||||
m[k] = trimValue(v)
|
|
||||||
case "descr":
|
|
||||||
if len(descr) == 0 {
|
|
||||||
descr = v
|
|
||||||
}
|
|
||||||
case "netname":
|
|
||||||
netname = v
|
|
||||||
case "whois": // "whois: whois.arin.net"
|
|
||||||
m["whois"] = v
|
|
||||||
case "referralserver": // "ReferralServer: whois://whois.ripe.net"
|
|
||||||
if strings.HasPrefix(v, "whois://") {
|
|
||||||
m["whois"] = v[len("whois://"):]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, ok := m["orgname"]
|
return ""
|
||||||
if !ok {
|
}
|
||||||
// Set orgname from either descr or netname for the frontent.
|
|
||||||
//
|
// isWhoisComment returns true if the string is empty or is a WHOIS comment.
|
||||||
// TODO(a.garipov): Perhaps don't do that in the V1 HTTP API?
|
func isWhoisComment(s string) (ok bool) {
|
||||||
if descr != "" {
|
return len(s) == 0 || s[0] == '#' || s[0] == '%'
|
||||||
m["orgname"] = trimValue(descr)
|
}
|
||||||
} else if netname != "" {
|
|
||||||
m["orgname"] = trimValue(netname)
|
// strmap is an alias for convenience.
|
||||||
|
type strmap = map[string]string
|
||||||
|
|
||||||
|
// whoisParse parses a subset of plain-text data from the WHOIS response into
|
||||||
|
// a string map.
|
||||||
|
func whoisParse(data string) (m strmap) {
|
||||||
|
m = strmap{}
|
||||||
|
|
||||||
|
var orgname string
|
||||||
|
lines := strings.Split(data, "\n")
|
||||||
|
for _, l := range lines {
|
||||||
|
if isWhoisComment(l) {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kv := strings.SplitN(l, ":", 2)
|
||||||
|
if len(kv) != 2 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
k := strings.ToLower(strings.TrimSpace(kv[0]))
|
||||||
|
v := strings.TrimSpace(kv[1])
|
||||||
|
if v == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch k {
|
||||||
|
case "orgname", "org-name":
|
||||||
|
k = "orgname"
|
||||||
|
v = trimValue(v)
|
||||||
|
orgname = v
|
||||||
|
case "city", "country":
|
||||||
|
v = trimValue(v)
|
||||||
|
case "descr", "netname":
|
||||||
|
k = "orgname"
|
||||||
|
v = coalesceStr(orgname, v)
|
||||||
|
orgname = v
|
||||||
|
case "whois":
|
||||||
|
k = "whois"
|
||||||
|
case "referralserver":
|
||||||
|
k = "whois"
|
||||||
|
v = strings.TrimPrefix(v, "whois://")
|
||||||
|
default:
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
m[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
|
@ -76,3 +76,77 @@ func TestWhois(t *testing.T) {
|
||||||
assert.Equal(t, "Imagiland", m["country"])
|
assert.Equal(t, "Imagiland", m["country"])
|
||||||
assert.Equal(t, "Nonreal", m["city"])
|
assert.Equal(t, "Nonreal", m["city"])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWhoisParse(t *testing.T) {
|
||||||
|
const (
|
||||||
|
city = "Nonreal"
|
||||||
|
country = "Imagiland"
|
||||||
|
orgname = "FakeOrgLLC"
|
||||||
|
whois = "whois.example.net"
|
||||||
|
)
|
||||||
|
|
||||||
|
testCases := []struct {
|
||||||
|
want strmap
|
||||||
|
name string
|
||||||
|
in string
|
||||||
|
}{{
|
||||||
|
want: strmap{},
|
||||||
|
name: "empty",
|
||||||
|
in: ``,
|
||||||
|
}, {
|
||||||
|
want: strmap{},
|
||||||
|
name: "comments",
|
||||||
|
in: "%\n#",
|
||||||
|
}, {
|
||||||
|
want: strmap{},
|
||||||
|
name: "no_colon",
|
||||||
|
in: "city",
|
||||||
|
}, {
|
||||||
|
want: strmap{},
|
||||||
|
name: "no_value",
|
||||||
|
in: "city:",
|
||||||
|
}, {
|
||||||
|
want: strmap{"city": city},
|
||||||
|
name: "city",
|
||||||
|
in: `city: ` + city,
|
||||||
|
}, {
|
||||||
|
want: strmap{"country": country},
|
||||||
|
name: "country",
|
||||||
|
in: `country: ` + country,
|
||||||
|
}, {
|
||||||
|
want: strmap{"orgname": orgname},
|
||||||
|
name: "orgname",
|
||||||
|
in: `orgname: ` + orgname,
|
||||||
|
}, {
|
||||||
|
want: strmap{"orgname": orgname},
|
||||||
|
name: "orgname_hyphen",
|
||||||
|
in: `org-name: ` + orgname,
|
||||||
|
}, {
|
||||||
|
want: strmap{"orgname": orgname},
|
||||||
|
name: "orgname_descr",
|
||||||
|
in: `descr: ` + orgname,
|
||||||
|
}, {
|
||||||
|
want: strmap{"orgname": orgname},
|
||||||
|
name: "orgname_netname",
|
||||||
|
in: `netname: ` + orgname,
|
||||||
|
}, {
|
||||||
|
want: strmap{"whois": whois},
|
||||||
|
name: "whois",
|
||||||
|
in: `whois: ` + whois,
|
||||||
|
}, {
|
||||||
|
want: strmap{"whois": whois},
|
||||||
|
name: "referralserver",
|
||||||
|
in: `referralserver: whois://` + whois,
|
||||||
|
}, {
|
||||||
|
want: strmap{},
|
||||||
|
name: "other",
|
||||||
|
in: `other: value`,
|
||||||
|
}}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
got := whoisParse(tc.in)
|
||||||
|
assert.Equal(t, tc.want, got)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue