416 lines
14 KiB
Go
416 lines
14 KiB
Go
package whois
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func parse(domain string, result string) {
|
|
os.WriteFile(domain+".txt", []byte(result), 0644)
|
|
ext := getExtension(domain)
|
|
secExt := getExtension(strings.TrimSuffix(domain, "."+ext))
|
|
_ = secExt
|
|
var data Result
|
|
var err error
|
|
switch ext {
|
|
case "cn":
|
|
data, err = dotCNParser(domain, result)
|
|
case "jp":
|
|
data, err = dotJPParser(domain, result)
|
|
case "tw":
|
|
data, err = dotTWParser(domain, result)
|
|
default:
|
|
data, err = commonParser(domain, result)
|
|
}
|
|
fmt.Println(err)
|
|
fmt.Println(data.domain, data.registerDate, data.expireDate, data.nsServers)
|
|
fmt.Println(data.exists, data.statusRaw, data.nsServers)
|
|
fmt.Printf("%+v\n%+v\n", data.adminInfo, data.registerInfo)
|
|
}
|
|
|
|
func commonParser(domain, data string) (Result, error) {
|
|
var res = Result{
|
|
domain: domain,
|
|
rawData: data,
|
|
}
|
|
var r, a, t PersonalInfo
|
|
|
|
split := strings.Split(data, "\n")
|
|
for _, line := range split {
|
|
line = strings.TrimSpace(line)
|
|
if !res.exists {
|
|
for _, token := range []string{"Domain not found.", "No match for", "No match", "No Data Found", "No entries found", "No match for domain", "No matching record", "No Found", "No Object"} {
|
|
if strings.HasPrefix(token, line) {
|
|
res.exists = false
|
|
return res, nil
|
|
}
|
|
}
|
|
}
|
|
if strings.HasPrefix(line, "Domain Name:") {
|
|
res.exists = true
|
|
res.nsServers = []string{}
|
|
res.domain = strings.TrimSpace(strings.TrimPrefix(line, "Domain Name:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registry Domain ID:") {
|
|
res.domainID = strings.TrimSpace(strings.TrimPrefix(line, "Registry Domain ID:"))
|
|
}
|
|
if strings.HasPrefix(line, "Updated Date:") {
|
|
res.updateDate = parseDate(strings.TrimSpace(strings.TrimPrefix(line, "Updated Date:")))
|
|
}
|
|
if strings.HasPrefix(line, "Creation Date:") {
|
|
res.registerDate = parseDate(strings.TrimSpace(strings.TrimPrefix(line, "Creation Date:")))
|
|
}
|
|
if strings.HasPrefix(line, "Registry Expiry Date:") {
|
|
res.expireDate = parseDate(strings.TrimSpace(strings.TrimPrefix(line, "Registry Expiry Date:")))
|
|
}
|
|
if strings.HasPrefix(line, "Registrar:") {
|
|
res.registar = strings.TrimSpace(strings.TrimPrefix(line, "Registrar:"))
|
|
}
|
|
if strings.HasPrefix(line, "Status:") {
|
|
res.statusRaw = strings.TrimSpace(strings.TrimPrefix(line, "Status:"))
|
|
}
|
|
if strings.HasPrefix(line, "Name Server:") {
|
|
res.nsServers = append(res.nsServers, strings.TrimSpace(strings.TrimPrefix(line, "Name Server:")))
|
|
}
|
|
if strings.HasPrefix(line, "DNSSEC:") {
|
|
res.dnssec = strings.TrimSpace(strings.TrimPrefix(line, "DNSSEC:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrar Registration Expiration Date:") {
|
|
res.expireDate = parseDate(strings.TrimSpace(strings.TrimPrefix(line, "Registrar Registration Expiration Date:")))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant Name:") {
|
|
r.Name = strings.TrimSpace(strings.TrimPrefix(line, "Registrant Name:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant Organization:") {
|
|
r.Org = strings.TrimSpace(strings.TrimPrefix(line, "Registrant Organization:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant Street:") {
|
|
r.Addr = strings.TrimSpace(strings.TrimPrefix(line, "Registrant Street:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant City:") {
|
|
r.City = strings.TrimSpace(strings.TrimPrefix(line, "Registrant City:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant State/Province:") {
|
|
r.State = strings.TrimSpace(strings.TrimPrefix(line, "Registrant State/Province:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant Postal Code:") {
|
|
r.Zip = strings.TrimSpace(strings.TrimPrefix(line, "Registrant Postal Code:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant Country:") {
|
|
r.Country = strings.TrimSpace(strings.TrimPrefix(line, "Registrant Country:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant Phone:") {
|
|
r.Phone = strings.TrimSpace(strings.TrimPrefix(line, "Registrant Phone:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant Phone Ext:") {
|
|
r.PhoneExt = strings.TrimSpace(strings.TrimPrefix(line, "Registrant Phone Ext:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant Fax:") {
|
|
r.Fax = strings.TrimSpace(strings.TrimPrefix(line, "Registrant Fax:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant Fax Ext:") {
|
|
r.FaxExt = strings.TrimSpace(strings.TrimPrefix(line, "Registrant Fax Ext:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant Email:") {
|
|
r.Email = strings.TrimSpace(strings.TrimPrefix(line, "Registrant Email:"))
|
|
}
|
|
if strings.HasPrefix(line, "Admin Name:") {
|
|
a.Name = strings.TrimSpace(strings.TrimPrefix(line, "Admin Name:"))
|
|
}
|
|
if strings.HasPrefix(line, "Admin Organization:") {
|
|
a.Org = strings.TrimSpace(strings.TrimPrefix(line, "Admin Organization:"))
|
|
}
|
|
if strings.HasPrefix(line, "Admin Street:") {
|
|
a.Addr = strings.TrimSpace(strings.TrimPrefix(line, "Admin Street:"))
|
|
}
|
|
if strings.HasPrefix(line, "Admin City:") {
|
|
a.City = strings.TrimSpace(strings.TrimPrefix(line, "Admin City:"))
|
|
}
|
|
if strings.HasPrefix(line, "Admin State/Province:") {
|
|
a.State = strings.TrimSpace(strings.TrimPrefix(line, "Admin State/Province:"))
|
|
}
|
|
if strings.HasPrefix(line, "Admin Postal Code:") {
|
|
a.Zip = strings.TrimSpace(strings.TrimPrefix(line, "Admin Postal Code:"))
|
|
}
|
|
if strings.HasPrefix(line, "Admin Country:") {
|
|
a.Country = strings.TrimSpace(strings.TrimPrefix(line, "Admin Country:"))
|
|
}
|
|
if strings.HasPrefix(line, "Admin Phone:") {
|
|
a.Phone = strings.TrimSpace(strings.TrimPrefix(line, "Admin Phone:"))
|
|
}
|
|
if strings.HasPrefix(line, "Admin Phone Ext:") {
|
|
a.PhoneExt = strings.TrimSpace(strings.TrimPrefix(line, "Admin Phone Ext:"))
|
|
}
|
|
if strings.HasPrefix(line, "Admin Fax:") {
|
|
a.Fax = strings.TrimSpace(strings.TrimPrefix(line, "Admin Fax:"))
|
|
}
|
|
if strings.HasPrefix(line, "Admin Fax Ext:") {
|
|
a.FaxExt = strings.TrimSpace(strings.TrimPrefix(line, "Admin Fax Ext:"))
|
|
}
|
|
if strings.HasPrefix(line, "Admin Email:") {
|
|
a.Email = strings.TrimSpace(strings.TrimPrefix(line, "Admin Email:"))
|
|
}
|
|
if strings.HasPrefix(line, "Tech Name:") {
|
|
t.Name = strings.TrimSpace(strings.TrimPrefix(line, "Tech Name:"))
|
|
}
|
|
if strings.HasPrefix(line, "Tech Organization:") {
|
|
t.Org = strings.TrimSpace(strings.TrimPrefix(line, "Tech Organization:"))
|
|
}
|
|
if strings.HasPrefix(line, "Tech Street:") {
|
|
t.Addr = strings.TrimSpace(strings.TrimPrefix(line, "Tech Street:"))
|
|
}
|
|
if strings.HasPrefix(line, "Tech City:") {
|
|
t.City = strings.TrimSpace(strings.TrimPrefix(line, "Tech City:"))
|
|
}
|
|
if strings.HasPrefix(line, "Tech State/Province:") {
|
|
t.State = strings.TrimSpace(strings.TrimPrefix(line, "Tech State/Province:"))
|
|
}
|
|
if strings.HasPrefix(line, "Tech Postal Code:") {
|
|
t.Zip = strings.TrimSpace(strings.TrimPrefix(line, "Tech Postal Code:"))
|
|
}
|
|
if strings.HasPrefix(line, "Tech Country:") {
|
|
t.Country = strings.TrimSpace(strings.TrimPrefix(line, "Tech Country:"))
|
|
}
|
|
if strings.HasPrefix(line, "Tech Phone:") {
|
|
t.Phone = strings.TrimSpace(strings.TrimPrefix(line, "Tech Phone:"))
|
|
}
|
|
if strings.HasPrefix(line, "Tech Phone Ext:") {
|
|
t.PhoneExt = strings.TrimSpace(strings.TrimPrefix(line, "Tech Phone Ext:"))
|
|
}
|
|
if strings.HasPrefix(line, "Tech Fax:") {
|
|
t.Fax = strings.TrimSpace(strings.TrimPrefix(line, "Tech Fax:"))
|
|
}
|
|
if strings.HasPrefix(line, "Tech Fax Ext:") {
|
|
t.FaxExt = strings.TrimSpace(strings.TrimPrefix(line, "Tech Fax Ext:"))
|
|
}
|
|
if strings.HasPrefix(line, "Tech Email:") {
|
|
t.Email = strings.TrimSpace(strings.TrimPrefix(line, "Tech Email:"))
|
|
}
|
|
}
|
|
res.registerInfo = r
|
|
res.adminInfo = a
|
|
res.techInfo = t
|
|
return res, nil
|
|
}
|
|
|
|
func dotCNParser(domain, data string) (Result, error) {
|
|
var res = Result{
|
|
domain: domain,
|
|
rawData: data,
|
|
}
|
|
var r PersonalInfo
|
|
if strings.HasPrefix("No matching record.", strings.TrimSpace(data)) {
|
|
res.exists = false
|
|
return res, nil
|
|
}
|
|
res.exists = true
|
|
split := strings.Split(data, "\n")
|
|
for _, line := range split {
|
|
line = strings.TrimSpace(line)
|
|
if strings.HasPrefix(line, "Domain Name:") {
|
|
res.nsServers = []string{}
|
|
res.domain = strings.TrimSpace(strings.TrimPrefix(line, "Domain Name:"))
|
|
}
|
|
if strings.HasPrefix(line, "ROID:") {
|
|
res.domainID = strings.TrimSpace(strings.TrimPrefix(line, "ROID:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registration Time:") {
|
|
res.registerDate = parseCNDate(strings.TrimSpace(strings.TrimPrefix(line, "Registration Time:")))
|
|
}
|
|
if strings.HasPrefix(line, "Expiration Time:") {
|
|
res.expireDate = parseCNDate(strings.TrimSpace(strings.TrimPrefix(line, "Expiration Time:")))
|
|
}
|
|
if strings.HasPrefix(line, "Sponsoring Registrar:") {
|
|
res.registar = strings.TrimSpace(strings.TrimPrefix(line, "Sponsoring Registrar:"))
|
|
}
|
|
if strings.HasPrefix(line, "Status:") {
|
|
res.statusRaw = strings.TrimSpace(strings.TrimPrefix(line, "Status:"))
|
|
}
|
|
if strings.HasPrefix(line, "Name Server:") {
|
|
res.nsServers = append(res.nsServers, strings.TrimSpace(strings.TrimPrefix(line, "Name Server:")))
|
|
}
|
|
if strings.HasPrefix(line, "DNSSEC:") {
|
|
res.dnssec = strings.TrimSpace(strings.TrimPrefix(line, "DNSSEC:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant:") {
|
|
r.Name = strings.TrimSpace(strings.TrimPrefix(line, "Registrant:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registrant Contact Email:") {
|
|
r.Email = strings.TrimSpace(strings.TrimPrefix(line, "Registrant Contact Email:"))
|
|
}
|
|
}
|
|
res.registerInfo = r
|
|
return res, nil
|
|
}
|
|
|
|
func dotJPParser(domain, data string) (Result, error) {
|
|
var res = Result{
|
|
domain: domain,
|
|
rawData: data,
|
|
}
|
|
var r PersonalInfo
|
|
split := strings.Split(data, "\n")
|
|
startAddress := false
|
|
for _, line := range split {
|
|
if strings.HasPrefix(line, "No match!!") {
|
|
res.exists = false
|
|
return res, nil
|
|
}
|
|
line = strings.TrimSpace(line)
|
|
if strings.HasPrefix(line, "[Domain Name]") {
|
|
res.nsServers = []string{}
|
|
res.domain = strings.TrimSpace(strings.TrimPrefix(line, "[Domain Name]"))
|
|
}
|
|
if strings.HasPrefix(line, "[登録者名]") {
|
|
r.Name = strings.TrimSpace(strings.TrimPrefix(line, "[登録者名]"))
|
|
}
|
|
if strings.HasPrefix(line, "[Name Server]") {
|
|
res.nsServers = append(res.nsServers, strings.TrimSpace(strings.TrimPrefix(line, "[Name Server]")))
|
|
}
|
|
if strings.HasPrefix(line, "[状態]") {
|
|
res.statusRaw += strings.TrimSpace(strings.TrimPrefix(line, "[状態]"))
|
|
}
|
|
if strings.HasPrefix(line, "[ロック状態]") {
|
|
res.statusRaw += strings.TrimSpace(strings.TrimPrefix(line, "[ロック状態]"))
|
|
}
|
|
if strings.HasPrefix(line, "[登録年月日]") {
|
|
res.registerDate = parseJPDate(strings.TrimSpace(strings.TrimPrefix(line, "[登録年月日]")), true)
|
|
}
|
|
if strings.HasPrefix(line, "[最終更新]") {
|
|
res.updateDate = parseJPDate(strings.TrimSpace(strings.TrimPrefix(line, "[最終更新]")), false)
|
|
}
|
|
if strings.HasPrefix(line, "[有効期限]") {
|
|
res.expireDate = parseJPDate(strings.TrimSpace(strings.TrimPrefix(line, "[有効期限]")), true)
|
|
}
|
|
if strings.HasPrefix(line, "[名前]") {
|
|
r.Name = strings.TrimSpace(strings.TrimPrefix(line, "[名前]"))
|
|
}
|
|
if strings.HasPrefix(line, "[組織名]") {
|
|
r.Org = strings.TrimSpace(strings.TrimPrefix(line, "[組織名]"))
|
|
}
|
|
if strings.HasPrefix(line, "[Email]") {
|
|
r.Email = strings.TrimSpace(strings.TrimPrefix(line, "[Email]"))
|
|
}
|
|
if strings.HasPrefix(line, "[住所]") {
|
|
r.Addr = strings.TrimSpace(strings.TrimPrefix(line, "[住所]"))
|
|
continue
|
|
}
|
|
if strings.HasPrefix(line, "[Postal Address]") {
|
|
startAddress = false
|
|
continue
|
|
}
|
|
if startAddress {
|
|
r.Addr += "\n" + line
|
|
}
|
|
if strings.HasPrefix(line, "[電話番号]") {
|
|
r.Phone = strings.TrimSpace(strings.TrimPrefix(line, "[電話番号]"))
|
|
}
|
|
if strings.HasPrefix(line, "[FAX番号]") {
|
|
r.Fax = strings.TrimSpace(strings.TrimPrefix(line, "[FAX番号]"))
|
|
break
|
|
}
|
|
}
|
|
res.registerInfo = r
|
|
return res, nil
|
|
}
|
|
|
|
func dotTWParser(domain, data string) (Result, error) {
|
|
var res = Result{
|
|
domain: domain,
|
|
rawData: data,
|
|
}
|
|
split := strings.Split(data, "\n")
|
|
startNs := false
|
|
var currentStatus uint8 = 0
|
|
var startIdx int
|
|
var r, a, t, p PersonalInfo
|
|
for idx, line := range split {
|
|
line = strings.TrimSpace(line)
|
|
if strings.HasPrefix(line, "No Found") || strings.HasPrefix(line, "網域名稱不合規定") {
|
|
res.exists = false
|
|
return res, nil
|
|
}
|
|
if strings.HasPrefix(line, "Domain Name:") {
|
|
res.exists = true
|
|
res.nsServers = []string{}
|
|
res.domain = strings.TrimSpace(strings.TrimPrefix(line, "Domain Name:"))
|
|
}
|
|
if strings.HasPrefix(line, "Registration Service Provider:") {
|
|
startNs = false
|
|
res.registar = strings.TrimSpace(strings.TrimPrefix(line, "Registration Service Provider:"))
|
|
}
|
|
if strings.HasPrefix(line, "Record created on") {
|
|
res.registerDate = parseCNDate(strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(line, "Record created on"), "(UTC+8)")))
|
|
}
|
|
if strings.HasPrefix(line, "Record expires on") {
|
|
res.expireDate = parseCNDate(strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(line, "Record expires on"), "(UTC+8)")))
|
|
}
|
|
if strings.HasPrefix(line, "Domain Status:") {
|
|
res.statusRaw = strings.TrimSpace(strings.TrimPrefix(line, "Domain Status:"))
|
|
}
|
|
if strings.HasPrefix(line, "Domain servers in listed order:") {
|
|
startNs = true
|
|
continue
|
|
}
|
|
if strings.HasPrefix(line, "Registrant:") {
|
|
currentStatus = 1
|
|
startIdx = idx
|
|
p = PersonalInfo{}
|
|
continue
|
|
}
|
|
if currentStatus > 0 {
|
|
if line == "(Redacted for privacy)" {
|
|
switch currentStatus {
|
|
case 1:
|
|
r = p
|
|
case 2:
|
|
a = p
|
|
case 3:
|
|
t = p
|
|
}
|
|
continue
|
|
}
|
|
switch idx - startIdx {
|
|
case 1:
|
|
p.Name = line
|
|
case 3:
|
|
p.Email = line
|
|
case 4:
|
|
p.Country = line
|
|
}
|
|
}
|
|
if startNs {
|
|
res.nsServers = append(res.nsServers, line)
|
|
}
|
|
}
|
|
res.registerInfo = r
|
|
res.adminInfo = a
|
|
res.techInfo = t
|
|
return res, nil
|
|
}
|
|
|
|
func parseDate(date string) time.Time {
|
|
t, _ := time.Parse("2006-01-02T15:04:05Z", date)
|
|
t = t.In(time.Local)
|
|
return t
|
|
}
|
|
|
|
func parseCNDate(date string) time.Time {
|
|
t, _ := time.ParseInLocation("2006-01-02 15:04:05", date, time.FixedZone("CST", 8*3600))
|
|
t = t.In(time.Local)
|
|
return t
|
|
}
|
|
|
|
func parseJPDate(date string, onlyMD bool) time.Time {
|
|
if onlyMD {
|
|
t, _ := time.ParseInLocation("2006/01/02", date, time.FixedZone("JST", 9*3600))
|
|
t = t.In(time.Local)
|
|
return t
|
|
}
|
|
t, _ := time.ParseInLocation("2006/01/02 15:04:05 (JST)", date, time.FixedZone("JST", 9*3600))
|
|
t = t.In(time.Local)
|
|
return t
|
|
}
|