140 lines
2.7 KiB
Go
140 lines
2.7 KiB
Go
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
|
|
}
|