package checker import ( "encoding/json" "fmt" "math" "net/http" "regexp" "strings" "time" "github.com/likexian/whois" ) type RdapResponseData struct { Events []struct { EventAction string `json:"eventAction"` EventDate string `json:"eventDate"` } `json:"events"` } type RdapServices struct { Services [][][]string `json:"services"` } func GetRdapServices() map[string]string { response, _ := http.Get("https://data.iana.org/rdap/dns.json") values := make(map[string]string) defer response.Body.Close() var data RdapServices json.NewDecoder(response.Body).Decode(&data) for _, value := range data.Services { for _, tld := range value[0] { values[tld] = value[1][0] } } return values } func ExtractTld(domain string) string { elements := strings.Split(domain, ".") if len(elements) == 1 { return elements[0] } return strings.Join(elements[1:], ".") } func RdapCheck(domain, service string) Domain { url := fmt.Sprintf("%sdomain/%s?jscard=1", service, domain) response, _ := http.Get(url) now := time.Now() defer response.Body.Close() var data RdapResponseData json.NewDecoder(response.Body).Decode(&data) for _, event := range data.Events { if event.EventAction == "expiration" { date, _ := time.Parse(time.RFC3339, event.EventDate) daysLeft := date.Sub(now).Hours() / 24 return Domain{ Name: domain, DaysLeft: math.Floor(daysLeft), Date: date.Format(time.DateTime), } } } return Domain{Name: domain, Failed: true} } func WhoisCheck(domain string) Domain { domainFailed := Domain{Name: domain, Failed: true} result, err := whois.Whois(domain) if err != nil { return domainFailed } now := time.Now() formats := []string{ "expiration date", "expiry date", "expires on", "paid-till", "renewal", "expires", "domain_datebilleduntil", "expiration", "registry expiry", "registrar registration expiration", } result = strings.ToLower(result) for _, format := range formats { r, _ := regexp.Compile(fmt.Sprintf(`%s\s*:?\s*([^\s]+)`, format)) for i, match := range r.FindStringSubmatch(result) { if i%2 == 1 { date, err := time.Parse(time.RFC3339, strings.ToUpper(match)) if err == nil { daysLeft := date.Sub(now).Hours() / 24 return Domain{ Name: domain, DaysLeft: math.Floor(daysLeft), Date: date.Format(time.DateTime), } } } } } return domainFailed } func CheckDomains(domains []string) []Domain { values := []Domain{} services := GetRdapServices() for _, domain := range domains { tld := ExtractTld(domain) service := services[tld] if service != "" { values = append(values, RdapCheck(domain, service)) } else { values = append(values, WhoisCheck(domain)) } } return values }