p, pre, br, b, img, separator, i, u, small, mark, code tags
2025-07-22 15:34:42 +03:00
|
|
|
extends Node
|
|
|
|
|
|
|
|
|
|
func fetch_image(url: String) -> ImageTexture:
|
|
|
|
|
var http_request = HTTPRequest.new()
|
|
|
|
|
add_child(http_request)
|
|
|
|
|
|
2025-08-06 16:03:09 +03:00
|
|
|
if url.is_empty():
|
|
|
|
|
return null
|
|
|
|
|
|
2025-08-09 20:39:04 +03:00
|
|
|
var request_headers = PackedStringArray()
|
|
|
|
|
request_headers.append("User-Agent: " + UserAgent.get_user_agent())
|
|
|
|
|
|
|
|
|
|
var error = http_request.request(url, request_headers)
|
p, pre, br, b, img, separator, i, u, small, mark, code tags
2025-07-22 15:34:42 +03:00
|
|
|
if error != OK:
|
|
|
|
|
print("Error making HTTP request: ", error)
|
|
|
|
|
http_request.queue_free()
|
|
|
|
|
return null
|
|
|
|
|
|
|
|
|
|
var response = await http_request.request_completed
|
|
|
|
|
|
|
|
|
|
var result = response[0] # HTTPClient.Result
|
|
|
|
|
var response_code = response[1] # int
|
|
|
|
|
var headers = response[2] # PackedStringArray
|
|
|
|
|
var body = response[3] # PackedByteArray
|
|
|
|
|
|
|
|
|
|
http_request.queue_free()
|
|
|
|
|
|
|
|
|
|
if result != HTTPRequest.RESULT_SUCCESS or response_code != 200:
|
|
|
|
|
print("Failed to fetch image. Result: ", result, " Response code: ", response_code)
|
|
|
|
|
return null
|
|
|
|
|
|
|
|
|
|
# Get content type from headers
|
|
|
|
|
var content_type = ""
|
|
|
|
|
for header in headers:
|
|
|
|
|
if header.to_lower().begins_with("content-type:"):
|
|
|
|
|
content_type = header.split(":")[1].strip_edges().to_lower()
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
var image: Image = Image.new()
|
|
|
|
|
var load_error
|
|
|
|
|
|
|
|
|
|
# Load image based on content type
|
2025-08-09 15:54:59 +03:00
|
|
|
if content_type.contains("jpeg") or content_type.contains("jpg") or url.to_lower().ends_with(".jpg") or url.to_lower().ends_with(".jpeg"):
|
p, pre, br, b, img, separator, i, u, small, mark, code tags
2025-07-22 15:34:42 +03:00
|
|
|
load_error = image.load_jpg_from_buffer(body)
|
2025-08-09 15:54:59 +03:00
|
|
|
elif content_type.contains("png") or url.to_lower().ends_with(".png"):
|
|
|
|
|
load_error = image.load_png_from_buffer(body)
|
p, pre, br, b, img, separator, i, u, small, mark, code tags
2025-07-22 15:34:42 +03:00
|
|
|
elif content_type.contains("webp") or url.to_lower().ends_with(".webp"):
|
|
|
|
|
load_error = image.load_webp_from_buffer(body)
|
|
|
|
|
elif content_type.contains("bmp"):
|
|
|
|
|
load_error = image.load_bmp_from_buffer(body)
|
|
|
|
|
elif content_type.contains("tga"):
|
|
|
|
|
load_error = image.load_tga_from_buffer(body)
|
|
|
|
|
else:
|
2025-08-09 15:54:59 +03:00
|
|
|
print("Unknown or missing content-type. Attempting bruteforce converting across JPEG, PNG and WebP...")
|
|
|
|
|
load_error = image.load_jpg_from_buffer(body)
|
p, pre, br, b, img, separator, i, u, small, mark, code tags
2025-07-22 15:34:42 +03:00
|
|
|
if load_error != OK:
|
2025-08-09 15:54:59 +03:00
|
|
|
load_error = image.load_png_from_buffer(body)
|
p, pre, br, b, img, separator, i, u, small, mark, code tags
2025-07-22 15:34:42 +03:00
|
|
|
if load_error != OK:
|
|
|
|
|
load_error = image.load_webp_from_buffer(body)
|
|
|
|
|
|
|
|
|
|
if load_error != OK:
|
|
|
|
|
print("Failed to load image from buffer. Content-Type: ", content_type, " Error: ", load_error)
|
|
|
|
|
return null
|
|
|
|
|
|
|
|
|
|
var texture = ImageTexture.create_from_image(image)
|
|
|
|
|
|
|
|
|
|
return texture
|
2025-08-16 13:57:14 +03:00
|
|
|
|
|
|
|
|
func fetch_text(url: String) -> String:
|
|
|
|
|
var http_request = HTTPRequest.new()
|
|
|
|
|
add_child(http_request)
|
|
|
|
|
|
|
|
|
|
if url.is_empty():
|
|
|
|
|
http_request.queue_free()
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
var request_headers = PackedStringArray()
|
|
|
|
|
request_headers.append("User-Agent: " + UserAgent.get_user_agent())
|
|
|
|
|
|
|
|
|
|
var error = http_request.request(url, request_headers)
|
|
|
|
|
if error != OK:
|
|
|
|
|
print("Error making HTTP request for text resource: ", url, " Error: ", error)
|
|
|
|
|
http_request.queue_free()
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
var response = await http_request.request_completed
|
|
|
|
|
|
|
|
|
|
var result = response[0] # HTTPClient.Result
|
|
|
|
|
var response_code = response[1] # int
|
|
|
|
|
var body = response[3] # PackedByteArray
|
|
|
|
|
|
|
|
|
|
http_request.queue_free()
|
|
|
|
|
|
|
|
|
|
if result != HTTPRequest.RESULT_SUCCESS or response_code != 200:
|
|
|
|
|
print("Failed to fetch text resource. URL: ", url, " Result: ", result, " Response code: ", response_code)
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
return body.get_string_from_utf8()
|
|
|
|
|
|
|
|
|
|
func fetch_external_resource(url: String, base_url: String = "") -> String:
|
|
|
|
|
var resolved_url = URLUtils.resolve_url(base_url, url)
|
|
|
|
|
|
|
|
|
|
if resolved_url.begins_with("http://") or resolved_url.begins_with("https://"):
|
|
|
|
|
return await fetch_text(resolved_url)
|
|
|
|
|
elif resolved_url.begins_with("gurt://"):
|
2025-08-27 20:56:29 +03:00
|
|
|
return fetch_gurt_resource(resolved_url)
|
2025-08-16 13:57:14 +03:00
|
|
|
else:
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
func fetch_gurt_resource(url: String) -> String:
|
|
|
|
|
if not GurtProtocol.is_gurt_domain(url):
|
|
|
|
|
return ""
|
|
|
|
|
|
2025-08-27 20:23:05 +03:00
|
|
|
var gurt_url = url
|
|
|
|
|
if not gurt_url.begins_with("gurt://"):
|
|
|
|
|
gurt_url = "gurt://" + gurt_url
|
2025-08-16 13:57:14 +03:00
|
|
|
|
2025-08-27 20:23:05 +03:00
|
|
|
if gurt_url.contains("localhost"):
|
|
|
|
|
gurt_url = gurt_url.replace("localhost", "127.0.0.1")
|
|
|
|
|
|
|
|
|
|
var client = GurtProtocolClient.new()
|
|
|
|
|
|
|
|
|
|
for ca_cert in CertificateManager.trusted_ca_certificates:
|
|
|
|
|
client.add_ca_certificate(ca_cert)
|
|
|
|
|
|
|
|
|
|
if not client.create_client(30):
|
|
|
|
|
print("GURT resource error: Failed to create client")
|
2025-08-16 13:57:14 +03:00
|
|
|
return ""
|
|
|
|
|
|
2025-08-27 20:23:05 +03:00
|
|
|
var host_domain = gurt_url
|
|
|
|
|
if host_domain.begins_with("gurt://"):
|
|
|
|
|
host_domain = host_domain.substr(7)
|
|
|
|
|
var slash_pos = host_domain.find("/")
|
|
|
|
|
if slash_pos != -1:
|
|
|
|
|
host_domain = host_domain.substr(0, slash_pos)
|
|
|
|
|
|
|
|
|
|
var response = client.request(gurt_url, {
|
|
|
|
|
"method": "GET",
|
|
|
|
|
"headers": {"Host": host_domain}
|
|
|
|
|
})
|
|
|
|
|
client.disconnect()
|
|
|
|
|
|
|
|
|
|
if not response or not response.is_success:
|
|
|
|
|
var error_msg = "Failed to load GURT resource"
|
|
|
|
|
if response:
|
|
|
|
|
error_msg += ": " + str(response.status_code) + " " + response.status_message
|
|
|
|
|
print("GURT resource error: ", error_msg)
|
|
|
|
|
return ""
|
2025-08-16 13:57:14 +03:00
|
|
|
|
2025-08-27 20:23:05 +03:00
|
|
|
return response.body.get_string_from_utf8()
|