extends RefCounted class_name GurtProtocol const DNS_API_URL = "http://localhost:8080" static func is_gurt_domain(url: String) -> bool: if url.begins_with("gurt://"): return true var parts = url.split(".") return parts.size() == 2 and not url.contains("://") static func parse_gurt_domain(url: String) -> Dictionary: print("Parsing URL: ", url) var domain_part = url if url.begins_with("gurt://"): domain_part = url.substr(7) # Remove "gurt://" var parts = domain_part.split(".") if parts.size() != 2: print("Invalid domain format: ", domain_part) return {} print("Parsed domain - name: ", parts[0], ", tld: ", parts[1]) return { "name": parts[0], "tld": parts[1], "display_url": domain_part } static func fetch_domain_info(name: String, tld: String) -> Dictionary: print("Fetching domain info for: ", name, ".", tld) var http_request = HTTPRequest.new() var tree = Engine.get_main_loop() tree.current_scene.add_child(http_request) http_request.timeout = 5.0 var url = DNS_API_URL + "/domain/" + name + "/" + tld print("DNS API URL: ", url) var error = http_request.request(url) if error != OK: print("HTTP request failed with error: ", error) http_request.queue_free() return {"error": "Failed to make DNS request"} var response = await http_request.request_completed http_request.queue_free() if response[1] == 0 and response[3].size() == 0: print("DNS API request timed out") return {"error": "DNS server is not responding"} var http_code = response[1] var body = response[3] print("DNS API response code: ", http_code) print("DNS API response body: ", body.get_string_from_utf8()) if http_code != 200: return {"error": "Domain not found or not approved"} var json = JSON.new() var parse_result = json.parse(body.get_string_from_utf8()) if parse_result != OK: print("JSON parse error: ", parse_result) return {"error": "Invalid JSON response from DNS server"} print("Domain info retrieved: ", json.data) return json.data static func fetch_index_html(ip: String) -> String: print("Fetching index.html from IP: ", ip) var http_request = HTTPRequest.new() var tree = Engine.get_main_loop() tree.current_scene.add_child(http_request) http_request.timeout = 5.0 var url = "http://" + ip + "/index.html" print("Fetching from URL: ", url) var error = http_request.request(url) if error != OK: print("HTTP request to IP failed with error: ", error) http_request.queue_free() return "" var response = await http_request.request_completed http_request.queue_free() if response[1] == 0 and response[3].size() == 0: print("Index.html request timed out") return "" var http_code = response[1] var body = response[3] print("IP response code: ", http_code) if http_code != 200: print("Failed to fetch index.html, HTTP code: ", http_code) return "" var html_content = body.get_string_from_utf8() print("Successfully fetched HTML content (", html_content.length(), " characters)") return html_content static func handle_gurt_domain(url: String) -> Dictionary: print("Handling GURT domain: ", url) var parsed = parse_gurt_domain(url) if parsed.is_empty(): return {"error": "Invalid domain format. Use: domain.tld", "html": create_error_page("Invalid domain format. Use: domain.tld")} var domain_info = await fetch_domain_info(parsed.name, parsed.tld) if domain_info.has("error"): return {"error": domain_info.error, "html": create_error_page(domain_info.error)} var html_content = await fetch_index_html(domain_info.ip) if html_content.is_empty(): var error_msg = "Failed to fetch index.html from " + domain_info.ip return {"error": error_msg, "html": create_error_page(error_msg)} return {"html": html_content, "display_url": parsed.display_url} static func get_error_type(error_message: String) -> Dictionary: if "DNS server is not responding" in error_message or "Domain not found" in error_message: return {"code": "ERR_NAME_NOT_RESOLVED", "title": "This site can't be reached", "icon": "🌐"} elif "timeout" in error_message.to_lower() or "timed out" in error_message.to_lower(): return {"code": "ERR_CONNECTION_TIMED_OUT", "title": "This site can't be reached", "icon": "⏰"} elif "Failed to fetch" in error_message or "HTTP request failed" in error_message: return {"code": "ERR_CONNECTION_REFUSED", "title": "This site can't be reached", "icon": "🚫"} elif "Invalid domain format" in error_message: return {"code": "ERR_INVALID_URL", "title": "This page isn't working", "icon": "⚠️"} else: return {"code": "ERR_UNKNOWN", "title": "Something went wrong", "icon": "❌"} static func create_error_page(error_message: String) -> String: var error_info = get_error_type(error_message) return """ """ + error_info.title + """ - GURT

""" + error_info.icon + """

""" + error_info.title + """

""" + error_message + """

""" + error_info.code + """

Try:

"""