File size: 4,031 Bytes
8a21bc0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
from flask import Flask, request, send_from_directory
import dns.resolver
import socket
import requests
from urllib.parse import urlparse
import dns.resolver
import socket

app = Flask(__name__)

@app.route('/')
def index():
    """Route handler for the home page"""
    try:
        return send_from_directory('.', 'index.html')
    except Exception as e:
        return str(e)

@app.route('/check', methods=['POST'])
def check_domain():
    """Check domain availability"""
    try:
        domain = request.json.get('domain', '').strip().lower().strip('/')
        if '://' in domain:
            domain = urlparse(domain).netloc
        result = check_domain_availability(domain) or {}
        return {
            "domain": domain,
            "available": result.get("available"),
            "method": result.get("method", None),
            "error": result.get("error", None)
        }
    except Exception as e:
        return { "domain": domain, "error": str(e) }

def check_domain_availability(domain):
    """Check domain availability using multiple methods."""
    # First try DNS resolution
    dns_exists, record_type = check_dns_records(domain)
    if dns_exists:
        return { "available": False, "method": f"DNS:{record_type}" }
    
    # Try RDAP
    rdap_status_code, rdap_base_url = check_rdap_records(domain)
    if rdap_status_code == 404:
        return { "available": True, "method": f"RDAP:{rdap_base_url}" }
    elif rdap_status_code == 200:
        return { "available": False, "method": f"RDAP:{rdap_base_url}" }

    # Fall back to WHOIS
    whois_server = get_whois_server(domain)
    if whois_server and no_whois_records(domain, whois_server):
        return {"available": True, "method": f"WHOIS:{whois_server}"}
    
def get_whois_server(domain):
    """Get WHOIS server from IANA root zone database."""
    try:
        response = requests.get(f'https://www.iana.org/whois?q={domain}')
        if 'whois:' in response.text.lower():
            for line in response.text.split('\n'):
                if 'whois:' in line.lower():
                    return line.split(':')[1].strip()
    except:
        pass
    return None

def check_dns_records(domain):
    """Check if domain exists in DNS by looking for common record types."""
    # Check NS records first as they're required for valid domains
    for record_type in ['NS', 'A', 'AAAA', 'MX', 'CNAME']:
        try:
            dns.resolver.resolve(domain, record_type)
            return True, record_type
        except:
            continue
    return False, None

def check_rdap_records(domain):
    try:
        bootstrap_url = "https://data.iana.org/rdap/dns.json"
        bootstrap_data = requests.get(bootstrap_url, timeout=5).json()
        
        tld = domain.split('.')[-1]
        rdap_base_url = None
        
        for service in bootstrap_data['services']:
            if tld in service[0]:
                rdap_base_url = service[1][0].strip('/')
                break
        
        if rdap_base_url:
            rdap_url = f"{rdap_base_url}/domain/{domain}"
            response = requests.get(rdap_url, timeout=5)
            return response.status_code, rdap_base_url
    except:
        pass
    return None, None

def no_whois_records(domain, whois_server) -> bool:
    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(5)
        sock.connect((whois_server, 43))
        sock.send(f"{domain}\r\n".encode())
        response = sock.recv(4096).decode(errors='ignore')
        sock.close()
        
        available_patterns = [
            'no match',
            'not found',
            'no entries found',
            'no data found',
            'not registered',
            'available',
            'status: free',
            'domain not found'
        ]
        
        response_lower = response.lower()
        for pattern in available_patterns:
            if pattern in response_lower:
                return True
    except:
        pass
    return False