Skip to content

Instantly share code, notes, and snippets.

@coderofsalvation
Last active May 17, 2024 08:02
Show Gist options
  • Save coderofsalvation/b2b111a2631fbdc8e76d6cab3bea8f17 to your computer and use it in GitHub Desktop.
Save coderofsalvation/b2b111a2631fbdc8e76d6cab3bea8f17 to your computer and use it in GitHub Desktop.
URI.gd: a Godot URL Parser #gdscript #openweb #https (document.location js-like object for Godot)
# URI/URL parser
#
# author: Leon van Kammen (coderofsalvation)
# SPDX-License-Identifier: MIT
# date: 16-05-2024
# comments: https://gist.github.com/coderofsalvation/b2b111a2631fbdc8e76d6cab3bea8f17
#
# Participants of the Open Web think & communicate in URI's: now with Godot (>=4) too!
# This class will not win the beauty contest related to RFC 3986, but here goes:
#
# USAGE:
#
# xrf = preload("res://URI.gd").new()
# print( URI.parse("https://foo.com/a/bc.gltf?bar=2#foo=2") )
# print( URI.parse("a/bc.gltf?a=1#foo=2") )
#
# OUTPUT:
# { "domain": "foo.com", "fragment": { "foo": { "string": "2", "x": <null>, "y": <null>, "color": <null>, "float": <null>, "int": <null> } }, "file": "bc.gltf", "URN": "https://foo.com/a/bc.gltf?bar=2#foo=2", "string": "https://foo.com/a/bc.gltf?bar=2#foo=2", "protocol": "https", "path": "a/bc.gltf", "query": { "bar": { "string": "2", "x": <null>, "y": <null>, "color": <null>, "float": <null>, "int": <null> } }, "hash": "#foo=2", "isLocal": false }
# { "domain": "", "fragment": { "foo": { "string": "2", "x": <null>, "y": <null>, "color": <null>, "float": <null>, "int": <null> } }, "file": "bc.gltf", "URN": "", "string": "a/bc.gltf?a=1#foo=2", "protocol": "", "path": "a/bc.gltf", "query": { "a": { "string": "1", "x": <null>, "y": <null>, "color": <null>, "float": <null>, "int": <null> } }, "hash": "#foo=2", "isLocal": true }
#
class_name URI
####################################################################################################
# URI Class
####################################################################################################
func parse(url: String) -> Dictionary:
var URI = {"domain":"","fragment":"","file":""}
var parts = ["string","protocol","path","query","hash"]
var urlregex = RegEx.new()
urlregex.compile("(\\w+:\\/\\/)?([^#\\?]+)?(\\?[^#]+)?(#.*)?")
var match = urlregex.search(url)
for i in range(0,parts.size()):
URI[ parts[i] ] = match.strings[i] if match.strings[i] else ""
if URI["path"]:
var pathParts:Array = URI["path"].split("/")
if pathParts.size() > 1 and (pathParts[0].find(".") != -1 || pathParts[0].find(":") != -1):
URI["domain"] = pathParts.pop_front()
URI["path"] = "/".join(pathParts)
pathParts = URI["path"].split("/")
if pathParts[-1].find(".") != -1:
URI["file"] = pathParts[-1]
URI["path"] = "/".join(pathParts)
URI["protocol"] = URI["protocol"].replace("://","") if URI["protocol"] else ""
URI["fragment"] = parseArgs( URI["hash"].substr(1) ) if URI["hash"] else {}
URI["query"] = parseArgs( URI["query"].substr(1) ) if URI["query"] else {}
URI["URN"] = URI["string"].replace("\\?.*","") if URI["domain"] else ""
URI["isLocal"] = true if !URI["domain"] else false
func parseArgs(fragment: String) -> Dictionary:
var ARG = {}
var items = fragment.split("&")
for item in items:
var key_value = item.split("=")
if key_value.size() > 1:
ARG[key_value[0]] = guess_type(key_value[1])
else:
ARG[key_value[0]] = ""
return ARG
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment