diff options
author | Hans Hagen <pragma@wxs.nl> | 2019-02-22 20:29:46 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg@phi-gamma.net> | 2019-02-22 20:29:46 +0100 |
commit | 7b271baae19db1528fbe6621bdf50af89a5a336b (patch) | |
tree | 4fc24a8f2be20aa90e90f6e1bcb62d69f4946235 /tex/context/base/mkiv/util-soc-imp-url.lua | |
parent | 67b9965fe473d18f13ed4c40f1e4e008eb870322 (diff) | |
download | context-7b271baae19db1528fbe6621bdf50af89a5a336b.tar.gz |
2019-02-22 19:43:00
Diffstat (limited to 'tex/context/base/mkiv/util-soc-imp-url.lua')
-rw-r--r-- | tex/context/base/mkiv/util-soc-imp-url.lua | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/util-soc-imp-url.lua b/tex/context/base/mkiv/util-soc-imp-url.lua new file mode 100644 index 000000000..fa472b650 --- /dev/null +++ b/tex/context/base/mkiv/util-soc-imp-url.lua @@ -0,0 +1,268 @@ +-- original file : url.lua +-- for more into : see util-soc.lua + +local tonumber, tostring, type = tonumber, tostring, type + +local gsub, sub, match, find, format, byte, char = string.gsub, string.sub, string.match, string.find, string.format, string.byte, string.char +local insert = table.insert + +local socket = socket or require("socket") + +local url = { + _VERSION = "URL 1.0.3", +} + +socket.url = url + +function url.escape(s) + return (gsub(s, "([^A-Za-z0-9_])", function(c) + return format("%%%02x", byte(c)) + end)) +end + +local function make_set(t) -- table.tohash + local s = { } + for i=1,#t do + s[t[i]] = true + end + return s +end + +local segment_set = make_set { + "-", "_", ".", "!", "~", "*", "'", "(", + ")", ":", "@", "&", "=", "+", "$", ",", +} + +local function protect_segment(s) + return gsub(s, "([^A-Za-z0-9_])", function(c) + if segment_set[c] then + return c + else + return format("%%%02X", byte(c)) + end + end) +end + +function url.unescape(s) + return (gsub(s, "%%(%x%x)", function(hex) + return char(tonumber(hex,16)) + end)) +end + +local function absolute_path(base_path, relative_path) + if find(relative_path,"^/") then + return relative_path + end + local path = gsub(base_path, "[^/]*$", "") + path = path .. relative_path + path = gsub(path, "([^/]*%./)", function (s) + if s ~= "./" then + return s + else + return "" + end + end) + path = gsub(path, "/%.$", "/") + local reduced + while reduced ~= path do + reduced = path + path = gsub(reduced, "([^/]*/%.%./)", function (s) + if s ~= "../../" then + return "" + else + return s + end + end) + end + path = gsub(reduced, "([^/]*/%.%.)$", function (s) + if s ~= "../.." then + return "" + else + return s + end + end) + return path +end + +function url.parse(url, default) + local parsed = { } + for k, v in next, default or parsed do + parsed[k] = v + end + if not url or url == "" then + return nil, "invalid url" + end + url = gsub(url, "#(.*)$", function(f) + parsed.fragment = f + return "" + end) + url = gsub(url, "^([%w][%w%+%-%.]*)%:", function(s) + parsed.scheme = s + return "" + end) + url = gsub(url, "^//([^/]*)", function(n) + parsed.authority = n + return "" + end) + url = gsub(url, "%?(.*)", function(q) + parsed.query = q + return "" + end) + url = gsub(url, "%;(.*)", function(p) + parsed.params = p + return "" + end) + if url ~= "" then + parsed.path = url + end + local authority = parsed.authority + if not authority then + return parsed + end + authority = gsub(authority,"^([^@]*)@", function(u) + parsed.userinfo = u + return "" + end) + authority = gsub(authority, ":([^:%]]*)$", function(p) + parsed.port = p + return "" + end) + if authority ~= "" then + parsed.host = match(authority, "^%[(.+)%]$") or authority + end + local userinfo = parsed.userinfo + if not userinfo then + return parsed + end + userinfo = gsub(userinfo, ":([^:]*)$", function(p) + parsed.password = p + return "" + end) + parsed.user = userinfo + return parsed +end + +function url.build(parsed) + local url = parsed.path or "" + if parsed.params then + url = url .. ";" .. parsed.params + end + if parsed.query then + url = url .. "?" .. parsed.query + end + local authority = parsed.authority + if parsed.host then + authority = parsed.host + if find(authority, ":") then -- IPv6? + authority = "[" .. authority .. "]" + end + if parsed.port then + authority = authority .. ":" .. tostring(parsed.port) + end + local userinfo = parsed.userinfo + if parsed.user then + userinfo = parsed.user + if parsed.password then + userinfo = userinfo .. ":" .. parsed.password + end + end + if userinfo then authority = userinfo .. "@" .. authority end + end + if authority then + url = "//" .. authority .. url + end + if parsed.scheme then + url = parsed.scheme .. ":" .. url + end + if parsed.fragment then + url = url .. "#" .. parsed.fragment + end + return url +end + +function url.absolute(base_url, relative_url) + local base_parsed + if type(base_url) == "table" then + base_parsed = base_url + base_url = url.build(base_parsed) + else + base_parsed = url.parse(base_url) + end + local relative_parsed = url.parse(relative_url) + if not base_parsed then + return relative_url + elseif not relative_parsed then + return base_url + elseif relative_parsed.scheme then + return relative_url + else + relative_parsed.scheme = base_parsed.scheme + if not relative_parsed.authority then + relative_parsed.authority = base_parsed.authority + if not relative_parsed.path then + relative_parsed.path = base_parsed.path + if not relative_parsed.params then + relative_parsed.params = base_parsed.params + if not relative_parsed.query then + relative_parsed.query = base_parsed.query + end + end + else + relative_parsed.path = absolute_path(base_parsed.path or "", relative_parsed.path) + end + end + return url.build(relative_parsed) + end +end + +function url.parse_path(path) + local parsed = { } + path = path or "" + gsub(path, "([^/]+)", function (s) + insert(parsed, s) + end) + for i=1,#parsed do + parsed[i] = url.unescape(parsed[i]) + end + if sub(path, 1, 1) == "/" then + parsed.is_absolute = 1 + end + if sub(path, -1, -1) == "/" then + parsed.is_directory = 1 + end + return parsed +end + +function url.build_path(parsed, unsafe) + local path = "" + local n = #parsed + if unsafe then + for i = 1, n-1 do + path = path .. parsed[i] .. "/" + end + if n > 0 then + path = path .. parsed[n] + if parsed.is_directory then + path = path .. "/" + end + end + else + for i = 1, n-1 do + path = path .. protect_segment(parsed[i]) .. "/" + end + if n > 0 then + path = path .. protect_segment(parsed[n]) + if parsed.is_directory then + path = path .. "/" + end + end + end + if parsed.is_absolute then + path = "/" .. path + end + return path +end + +package.loaded["socket.url"] = url + +return url |