url.lua: separate remove_dot_components() from absolute_path(); also use in _M.absolute() even when not merging

This commit is contained in:
E. Westbrook 2018-08-21 08:03:51 -06:00
parent 17a95c126a
commit c905b5d44f
2 changed files with 40 additions and 23 deletions

View File

@ -77,17 +77,12 @@ function _M.unescape(s)
end end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Builds a path from a base path and a relative path -- Removes '..' and '.' components appropriately from a path.
-- Input -- Input
-- base_path -- path
-- relative_path
-- Returns -- Returns
-- corresponding absolute path -- dot-normalized path
----------------------------------------------------------------------------- local function remove_dot_components(path)
local function absolute_path(base_path, relative_path)
if string.sub(relative_path, 1, 1) == "/" then return relative_path end
local path = string.gsub(base_path, "[^/]*$", "")
path = path .. relative_path
repeat repeat
local was = path local was = path
path = path:gsub('/%./', '/') path = path:gsub('/%./', '/')
@ -103,6 +98,23 @@ local function absolute_path(base_path, relative_path)
return path return path
end end
-----------------------------------------------------------------------------
-- Builds a path from a base path and a relative path
-- Input
-- base_path
-- relative_path
-- Returns
-- corresponding absolute path
-----------------------------------------------------------------------------
local function absolute_path(base_path, relative_path)
if string.sub(relative_path, 1, 1) == "/" then
return remove_dot_components(relative_path) end
base_path = base_path:gsub("[^/]*$", "")
local path = base_path .. relative_path
path = remove_dot_components(path)
return path
end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Parses a url and returns a table with all its parts according to RFC 2396 -- Parses a url and returns a table with all its parts according to RFC 2396
-- The following grammar describes the names given to the URL parts -- The following grammar describes the names given to the URL parts
@ -225,10 +237,14 @@ function _M.absolute(base_url, relative_url)
else else
base_parsed = _M.parse(base_url) base_parsed = _M.parse(base_url)
end end
local result
local relative_parsed = _M.parse(relative_url) local relative_parsed = _M.parse(relative_url)
if not base_parsed then return relative_url if not base_parsed then
elseif not relative_parsed then return base_url result = relative_url
elseif relative_parsed.scheme then return relative_url elseif not relative_parsed then
result = base_url
elseif relative_parsed.scheme then
result = relative_url
else else
relative_parsed.scheme = base_parsed.scheme relative_parsed.scheme = base_parsed.scheme
if not relative_parsed.authority then if not relative_parsed.authority then
@ -246,8 +262,9 @@ function _M.absolute(base_url, relative_url)
relative_parsed.path) relative_parsed.path)
end end
end end
return _M.build(relative_parsed) result = _M.build(relative_parsed)
end end
return remove_dot_components(result)
end end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------

View File

@ -627,10 +627,10 @@ check_absolute_url("http://a/b/c/d;p?q#f", "/g", "http://a/g")
check_absolute_url("http://a/b/c/d;p?q#f", "//g", "http://g") check_absolute_url("http://a/b/c/d;p?q#f", "//g", "http://g")
check_absolute_url("http://a/b/c/d;p?q#f", "?y", "http://a/b/c/d;p?y") check_absolute_url("http://a/b/c/d;p?q#f", "?y", "http://a/b/c/d;p?y")
check_absolute_url("http://a/b/c/d;p?q#f", "g?y", "http://a/b/c/g?y") check_absolute_url("http://a/b/c/d;p?q#f", "g?y", "http://a/b/c/g?y")
check_absolute_url("http://a/b/c/d;p?q#f", "g?y/./x", "http://a/b/c/g?y/./x") check_absolute_url("http://a/b/c/d;p?q#f", "g?y/./x", "http://a/b/c/g?y/x")
check_absolute_url("http://a/b/c/d;p?q#f", "#s", "http://a/b/c/d;p?q#s") check_absolute_url("http://a/b/c/d;p?q#f", "#s", "http://a/b/c/d;p?q#s")
check_absolute_url("http://a/b/c/d;p?q#f", "g#s", "http://a/b/c/g#s") check_absolute_url("http://a/b/c/d;p?q#f", "g#s", "http://a/b/c/g#s")
check_absolute_url("http://a/b/c/d;p?q#f", "g#s/./x", "http://a/b/c/g#s/./x") check_absolute_url("http://a/b/c/d;p?q#f", "g#s/./x", "http://a/b/c/g#s/x")
check_absolute_url("http://a/b/c/d;p?q#f", "g?y#s", "http://a/b/c/g?y#s") check_absolute_url("http://a/b/c/d;p?q#f", "g?y#s", "http://a/b/c/g?y#s")
check_absolute_url("http://a/b/c/d;p?q#f", ";x", "http://a/b/c/d;x") check_absolute_url("http://a/b/c/d;p?q#f", ";x", "http://a/b/c/d;x")
check_absolute_url("http://a/b/c/d;p?q#f", "g;x", "http://a/b/c/g;x") check_absolute_url("http://a/b/c/d;p?q#f", "g;x", "http://a/b/c/g;x")
@ -655,8 +655,8 @@ check_absolute_url("http://a/b/c/d;p?q#f", "../..", "http://a/")
check_absolute_url("http://a/b/c/d;p?q#f", "../../", "http://a/") check_absolute_url("http://a/b/c/d;p?q#f", "../../", "http://a/")
check_absolute_url("http://a/b/c/d;p?q#f", "../../g", "http://a/g") check_absolute_url("http://a/b/c/d;p?q#f", "../../g", "http://a/g")
check_absolute_url("http://a/b/c/d;p?q#f", "", "http://a/b/c/d;p?q#f") check_absolute_url("http://a/b/c/d;p?q#f", "", "http://a/b/c/d;p?q#f")
check_absolute_url("http://a/b/c/d;p?q#f", "/./g", "http://a/./g") check_absolute_url("http://a/b/c/d;p?q#f", "/./g", "http://a/g")
check_absolute_url("http://a/b/c/d;p?q#f", "/../g", "http://a/../g") check_absolute_url("http://a/b/c/d;p?q#f", "/../g", "http://a/g")
check_absolute_url("http://a/b/c/d;p?q#f", "g.", "http://a/b/c/g.") check_absolute_url("http://a/b/c/d;p?q#f", "g.", "http://a/b/c/g.")
check_absolute_url("http://a/b/c/d;p?q#f", ".g", "http://a/b/c/.g") check_absolute_url("http://a/b/c/d;p?q#f", ".g", "http://a/b/c/.g")
check_absolute_url("http://a/b/c/d;p?q#f", "g..", "http://a/b/c/g..") check_absolute_url("http://a/b/c/d;p?q#f", "g..", "http://a/b/c/g..")