From 3a4d2e24c459a38ac21c9985a4e4c8f57ac836ff Mon Sep 17 00:00:00 2001 From: Leon van Kammen Date: Fri, 17 May 2024 17:28:19 +0200 Subject: [PATCH] main: work in progress [might break] --- README.md | 18 +++++++++++++++++ URI.gd | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 README.md create mode 100644 URI.gd diff --git a/README.md b/README.md new file mode 100644 index 0000000..7a097e1 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# URI/URL parser + +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": , "y": , "color": , "float": , "int": } }, "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": , "y": , "color": , "float": , "int": } }, "hash": "#foo=2", "isLocal": false } + { "domain": "", "fragment": { "foo": { "string": "2", "x": , "y": , "color": , "float": , "int": } }, "file": "bc.gltf", "URN": "", "string": "a/bc.gltf?a=1#foo=2", "protocol": "", "path": "a/bc.gltf", "query": { "a": { "string": "1", "x": , "y": , "color": , "float": , "int": } }, "hash": "#foo=2", "isLocal": true } +``` diff --git a/URI.gd b/URI.gd new file mode 100644 index 0000000..fed6239 --- /dev/null +++ b/URI.gd @@ -0,0 +1,59 @@ +# 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": , "y": , "color": , "float": , "int": } }, "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": , "y": , "color": , "float": , "int": } }, "hash": "#foo=2", "isLocal": false } +# { "domain": "", "fragment": { "foo": { "string": "2", "x": , "y": , "color": , "float": , "int": } }, "file": "bc.gltf", "URN": "", "string": "a/bc.gltf?a=1#foo=2", "protocol": "", "path": "a/bc.gltf", "query": { "a": { "string": "1", "x": , "y": , "color": , "float": , "int": } }, "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