123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- package publicsuffix
- import (
- "fmt"
- "net/http/cookiejar"
- "strings"
- )
- var List cookiejar.PublicSuffixList = list{}
- type list struct{}
- func (list) PublicSuffix(domain string) string {
- ps, _ := PublicSuffix(domain)
- return ps
- }
- func (list) String() string {
- return version
- }
- func PublicSuffix(domain string) (publicSuffix string, icann bool) {
- lo, hi := uint32(0), uint32(numTLD)
- s, suffix, icannNode, wildcard := domain, len(domain), false, false
- loop:
- for {
- dot := strings.LastIndex(s, ".")
- if wildcard {
- icann = icannNode
- suffix = 1 + dot
- }
- if lo == hi {
- break
- }
- f := find(s[1+dot:], lo, hi)
- if f == notFound {
- break
- }
- u := nodes[f] >> (nodesBitsTextOffset + nodesBitsTextLength)
- icannNode = u&(1<<nodesBitsICANN-1) != 0
- u >>= nodesBitsICANN
- u = children[u&(1<<nodesBitsChildren-1)]
- lo = u & (1<<childrenBitsLo - 1)
- u >>= childrenBitsLo
- hi = u & (1<<childrenBitsHi - 1)
- u >>= childrenBitsHi
- switch u & (1<<childrenBitsNodeType - 1) {
- case nodeTypeNormal:
- suffix = 1 + dot
- case nodeTypeException:
- suffix = 1 + len(s)
- break loop
- }
- u >>= childrenBitsNodeType
- wildcard = u&(1<<childrenBitsWildcard-1) != 0
- if !wildcard {
- icann = icannNode
- }
- if dot == -1 {
- break
- }
- s = s[:dot]
- }
- if suffix == len(domain) {
-
- return domain[1+strings.LastIndex(domain, "."):], icann
- }
- return domain[suffix:], icann
- }
- const notFound uint32 = 1<<32 - 1
- func find(label string, lo, hi uint32) uint32 {
- for lo < hi {
- mid := lo + (hi-lo)/2
- s := nodeLabel(mid)
- if s < label {
- lo = mid + 1
- } else if s == label {
- return mid
- } else {
- hi = mid
- }
- }
- return notFound
- }
- func nodeLabel(i uint32) string {
- x := nodes[i]
- length := x & (1<<nodesBitsTextLength - 1)
- x >>= nodesBitsTextLength
- offset := x & (1<<nodesBitsTextOffset - 1)
- return text[offset : offset+length]
- }
- func EffectiveTLDPlusOne(domain string) (string, error) {
- if strings.HasPrefix(domain, ".") || strings.HasSuffix(domain, ".") || strings.Contains(domain, "..") {
- return "", fmt.Errorf("publicsuffix: empty label in domain %q", domain)
- }
- suffix, _ := PublicSuffix(domain)
- if len(domain) <= len(suffix) {
- return "", fmt.Errorf("publicsuffix: cannot derive eTLD+1 for domain %q", domain)
- }
- i := len(domain) - len(suffix) - 1
- if domain[i] != '.' {
- return "", fmt.Errorf("publicsuffix: invalid public suffix %q for domain %q", suffix, domain)
- }
- return domain[1+strings.LastIndex(domain[:i], "."):], nil
- }
|