dip/vendor/github.com/likexian/whois-go/whois.go
2019-12-22 18:20:45 +01:00

143 lines
3.0 KiB
Go

/*
* Copyright 2014-2019 Li Kexian
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Go module for domain and ip whois info query
* https://www.likexian.com/
*/
package whois
import (
"fmt"
"io/ioutil"
"net"
"strings"
"time"
)
const (
// IANA_WHOIS_SERVER is iana whois server
IANA_WHOIS_SERVER = "whois.iana.org"
// DOMAIN_WHOIS_SERVER is tld whois server
DOMAIN_WHOIS_SERVER = "whois-servers.net"
// WHOIS_PORT is default whois port
WHOIS_PORT = "43"
)
// Version returns package version
func Version() string {
return "1.3.0"
}
// Author returns package author
func Author() string {
return "[Li Kexian](https://www.likexian.com/)"
}
// License returns package license
func License() string {
return "Licensed under the Apache License 2.0"
}
// Whois do the whois query and returns whois info
func Whois(domain string, servers ...string) (result string, err error) {
domain = strings.Trim(strings.TrimSpace(domain), ".")
if domain == "" {
err = fmt.Errorf("Domain is empty")
return
}
result, err = query(domain, servers...)
if err != nil {
return
}
token := "Registrar WHOIS Server:"
if IsIpv4(domain) {
token = "whois:"
}
start := strings.Index(result, token)
if start == -1 {
return
}
start += len(token)
end := strings.Index(result[start:], "\n")
server := strings.TrimSpace(result[start : start+end])
if server == "" {
return
}
tmpResult, err := query(domain, server)
if err != nil {
return
}
result += tmpResult
return
}
// query do the query
func query(domain string, servers ...string) (result string, err error) {
server := IANA_WHOIS_SERVER
if len(servers) == 0 || servers[0] == "" {
if !IsIpv4(domain) {
domains := strings.Split(domain, ".")
if len(domains) > 1 {
ext := domains[len(domains)-1]
if strings.Contains(ext, "/") {
ext = strings.Split(ext, "/")[0]
}
server = ext + "." + DOMAIN_WHOIS_SERVER
}
}
} else {
server = strings.ToLower(servers[0])
if server == "whois.arin.net" {
domain = "n + " + domain
}
}
conn, e := net.DialTimeout("tcp", net.JoinHostPort(server, WHOIS_PORT), time.Second*30)
if e != nil {
err = e
return
}
defer conn.Close()
_ = conn.SetReadDeadline(time.Now().Add(time.Second * 30))
_, err = conn.Write([]byte(domain + "\r\n"))
if err != nil {
return
}
buffer, err := ioutil.ReadAll(conn)
if err != nil {
return
}
result = string(buffer)
return
}
// IsIpv4 returns string is an ipv4 ip
func IsIpv4(ip string) bool {
i := net.ParseIP(ip)
return i.To4() != nil
}