92 lines
2.1 KiB
Go
92 lines
2.1 KiB
Go
package whois
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"golang.org/x/net/idna"
|
|
)
|
|
|
|
type lookupTargetKind int
|
|
|
|
const (
|
|
lookupTargetDomain lookupTargetKind = iota
|
|
lookupTargetIP
|
|
lookupTargetASN
|
|
)
|
|
|
|
func normalizeQueryDomainInput(domain string) (string, error) {
|
|
domain = strings.Trim(strings.TrimSpace(domain), ".")
|
|
if domain == "" {
|
|
return "", errors.New("whois: domain is empty")
|
|
}
|
|
if strings.ContainsAny(domain, "/\\") {
|
|
return "", fmt.Errorf("whois: invalid domain=%q", domain)
|
|
}
|
|
|
|
if IsASN(domain) {
|
|
if strings.HasPrefix(strings.ToUpper(domain), "AS") {
|
|
return strings.ToUpper(domain), nil
|
|
}
|
|
return "AS" + strings.ToUpper(domain), nil
|
|
}
|
|
|
|
if ip := net.ParseIP(domain); ip != nil {
|
|
return ip.String(), nil
|
|
}
|
|
|
|
ascii, err := idna.Lookup.ToASCII(domain)
|
|
if err != nil {
|
|
return "", fmt.Errorf("whois: invalid domain=%q: %w", domain, err)
|
|
}
|
|
ascii = strings.ToLower(strings.Trim(ascii, "."))
|
|
if ascii == "" {
|
|
return "", errors.New("whois: domain is empty")
|
|
}
|
|
return ascii, nil
|
|
}
|
|
|
|
func normalizeLookupDomainInput(domain string) (string, error) {
|
|
normalized, kind, err := normalizeLookupTargetInput(domain)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if kind != lookupTargetDomain {
|
|
return "", fmt.Errorf("whois/lookup: invalid domain=%q", domain)
|
|
}
|
|
return normalized, nil
|
|
}
|
|
|
|
func normalizeLookupTargetInput(input string) (string, lookupTargetKind, error) {
|
|
normalized, err := normalizeQueryDomainInput(input)
|
|
if err != nil {
|
|
return "", lookupTargetDomain, err
|
|
}
|
|
if IsASN(normalized) {
|
|
return normalized, lookupTargetASN, nil
|
|
}
|
|
if net.ParseIP(normalized) != nil {
|
|
return normalized, lookupTargetIP, nil
|
|
}
|
|
return normalized, lookupTargetDomain, nil
|
|
}
|
|
|
|
func normalizeASNNumeric(asn string) (string, error) {
|
|
asn = strings.TrimSpace(strings.ToUpper(asn))
|
|
if !IsASN(asn) {
|
|
return "", fmt.Errorf("whois/rdap: invalid asn=%q", asn)
|
|
}
|
|
asn = strings.TrimPrefix(asn, "AS")
|
|
asn = strings.TrimSpace(asn)
|
|
if asn == "" {
|
|
return "", fmt.Errorf("whois/rdap: invalid asn=%q", asn)
|
|
}
|
|
if _, err := strconv.ParseUint(asn, 10, 32); err != nil {
|
|
return "", fmt.Errorf("whois/rdap: invalid asn=%q: %w", asn, err)
|
|
}
|
|
return asn, nil
|
|
}
|