aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/url.lua51
-rw-r--r--test/urltest.lua8
2 files changed, 38 insertions, 21 deletions
diff --git a/src/url.lua b/src/url.lua
index 29b6734..a354ab5 100644
--- a/src/url.lua
+++ b/src/url.lua
@@ -77,24 +77,19 @@ function _M.unescape(s)
77end 77end
78 78
79----------------------------------------------------------------------------- 79-----------------------------------------------------------------------------
80-- Builds a path from a base path and a relative path 80-- Removes '..' and '.' components appropriately from a path.
81-- Input 81-- Input
82-- base_path 82-- path
83-- relative_path
84-- Returns 83-- Returns
85-- corresponding absolute path 84-- dot-normalized path
86----------------------------------------------------------------------------- 85local function remove_dot_components(path)
87local function absolute_path(base_path, relative_path)
88 if string.sub(relative_path, 1, 1) == "/" then return relative_path end
89 local path = string.gsub(base_path, "[^/]*$", "")
90 path = path .. relative_path
91 repeat 86 repeat
92 local was = path 87 local was = path
93 path = path:gsub('/%./', '/') 88 path = path:gsub('/%./', '/')
94 until path == was 89 until path == was
95 repeat 90 repeat
96 local was = path 91 local was = path
97 path = path:gsub('[^/]+/%.%./([^/]+)', '%1') 92 path = path:gsub('[^/]+/%.%./([^/]+)', '%1')
98 until path == was 93 until path == was
99 path = path:gsub('[^/]+/%.%./*$', '') 94 path = path:gsub('[^/]+/%.%./*$', '')
100 path = path:gsub('/%.%.$', '/') 95 path = path:gsub('/%.%.$', '/')
@@ -104,6 +99,23 @@ local function absolute_path(base_path, relative_path)
104end 99end
105 100
106----------------------------------------------------------------------------- 101-----------------------------------------------------------------------------
102-- Builds a path from a base path and a relative path
103-- Input
104-- base_path
105-- relative_path
106-- Returns
107-- corresponding absolute path
108-----------------------------------------------------------------------------
109local function absolute_path(base_path, relative_path)
110 if string.sub(relative_path, 1, 1) == "/" then
111 return remove_dot_components(relative_path) end
112 base_path = base_path:gsub("[^/]*$", "")
113 local path = base_path .. relative_path
114 path = remove_dot_components(path)
115 return path
116end
117
118-----------------------------------------------------------------------------
107-- Parses a url and returns a table with all its parts according to RFC 2396 119-- Parses a url and returns a table with all its parts according to RFC 2396
108-- The following grammar describes the names given to the URL parts 120-- The following grammar describes the names given to the URL parts
109-- <url> ::= <scheme>://<authority>/<path>;<params>?<query>#<fragment> 121-- <url> ::= <scheme>://<authority>/<path>;<params>?<query>#<fragment>
@@ -225,10 +237,14 @@ function _M.absolute(base_url, relative_url)
225 else 237 else
226 base_parsed = _M.parse(base_url) 238 base_parsed = _M.parse(base_url)
227 end 239 end
240 local result
228 local relative_parsed = _M.parse(relative_url) 241 local relative_parsed = _M.parse(relative_url)
229 if not base_parsed then return relative_url 242 if not base_parsed then
230 elseif not relative_parsed then return base_url 243 result = relative_url
231 elseif relative_parsed.scheme then return relative_url 244 elseif not relative_parsed then
245 result = base_url
246 elseif relative_parsed.scheme then
247 result = relative_url
232 else 248 else
233 relative_parsed.scheme = base_parsed.scheme 249 relative_parsed.scheme = base_parsed.scheme
234 if not relative_parsed.authority then 250 if not relative_parsed.authority then
@@ -246,8 +262,9 @@ function _M.absolute(base_url, relative_url)
246 relative_parsed.path) 262 relative_parsed.path)
247 end 263 end
248 end 264 end
249 return _M.build(relative_parsed) 265 result = _M.build(relative_parsed)
250 end 266 end
267 return remove_dot_components(result)
251end 268end
252 269
253----------------------------------------------------------------------------- 270-----------------------------------------------------------------------------
diff --git a/test/urltest.lua b/test/urltest.lua
index 63a33ea..649be88 100644
--- a/test/urltest.lua
+++ b/test/urltest.lua
@@ -627,10 +627,10 @@ check_absolute_url("http://a/b/c/d;p?q#f", "/g", "http://a/g")
627check_absolute_url("http://a/b/c/d;p?q#f", "//g", "http://g") 627check_absolute_url("http://a/b/c/d;p?q#f", "//g", "http://g")
628check_absolute_url("http://a/b/c/d;p?q#f", "?y", "http://a/b/c/d;p?y") 628check_absolute_url("http://a/b/c/d;p?q#f", "?y", "http://a/b/c/d;p?y")
629check_absolute_url("http://a/b/c/d;p?q#f", "g?y", "http://a/b/c/g?y") 629check_absolute_url("http://a/b/c/d;p?q#f", "g?y", "http://a/b/c/g?y")
630check_absolute_url("http://a/b/c/d;p?q#f", "g?y/./x", "http://a/b/c/g?y/./x") 630check_absolute_url("http://a/b/c/d;p?q#f", "g?y/./x", "http://a/b/c/g?y/x")
631check_absolute_url("http://a/b/c/d;p?q#f", "#s", "http://a/b/c/d;p?q#s") 631check_absolute_url("http://a/b/c/d;p?q#f", "#s", "http://a/b/c/d;p?q#s")
632check_absolute_url("http://a/b/c/d;p?q#f", "g#s", "http://a/b/c/g#s") 632check_absolute_url("http://a/b/c/d;p?q#f", "g#s", "http://a/b/c/g#s")
633check_absolute_url("http://a/b/c/d;p?q#f", "g#s/./x", "http://a/b/c/g#s/./x") 633check_absolute_url("http://a/b/c/d;p?q#f", "g#s/./x", "http://a/b/c/g#s/x")
634check_absolute_url("http://a/b/c/d;p?q#f", "g?y#s", "http://a/b/c/g?y#s") 634check_absolute_url("http://a/b/c/d;p?q#f", "g?y#s", "http://a/b/c/g?y#s")
635check_absolute_url("http://a/b/c/d;p?q#f", ";x", "http://a/b/c/d;x") 635check_absolute_url("http://a/b/c/d;p?q#f", ";x", "http://a/b/c/d;x")
636check_absolute_url("http://a/b/c/d;p?q#f", "g;x", "http://a/b/c/g;x") 636check_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/")
655check_absolute_url("http://a/b/c/d;p?q#f", "../../", "http://a/") 655check_absolute_url("http://a/b/c/d;p?q#f", "../../", "http://a/")
656check_absolute_url("http://a/b/c/d;p?q#f", "../../g", "http://a/g") 656check_absolute_url("http://a/b/c/d;p?q#f", "../../g", "http://a/g")
657check_absolute_url("http://a/b/c/d;p?q#f", "", "http://a/b/c/d;p?q#f") 657check_absolute_url("http://a/b/c/d;p?q#f", "", "http://a/b/c/d;p?q#f")
658check_absolute_url("http://a/b/c/d;p?q#f", "/./g", "http://a/./g") 658check_absolute_url("http://a/b/c/d;p?q#f", "/./g", "http://a/g")
659check_absolute_url("http://a/b/c/d;p?q#f", "/../g", "http://a/../g") 659check_absolute_url("http://a/b/c/d;p?q#f", "/../g", "http://a/g")
660check_absolute_url("http://a/b/c/d;p?q#f", "g.", "http://a/b/c/g.") 660check_absolute_url("http://a/b/c/d;p?q#f", "g.", "http://a/b/c/g.")
661check_absolute_url("http://a/b/c/d;p?q#f", ".g", "http://a/b/c/.g") 661check_absolute_url("http://a/b/c/d;p?q#f", ".g", "http://a/b/c/.g")
662check_absolute_url("http://a/b/c/d;p?q#f", "g..", "http://a/b/c/g..") 662check_absolute_url("http://a/b/c/d;p?q#f", "g..", "http://a/b/c/g..")