diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/url.lua | 64 |
1 files changed, 21 insertions, 43 deletions
diff --git a/src/url.lua b/src/url.lua index 0a3a80a..110ea94 100644 --- a/src/url.lua +++ b/src/url.lua | |||
| @@ -77,34 +77,6 @@ function _M.unescape(s) | |||
| 77 | end | 77 | end |
| 78 | 78 | ||
| 79 | ----------------------------------------------------------------------------- | 79 | ----------------------------------------------------------------------------- |
| 80 | -- Removes '..' and '.' components appropriately from a path. | ||
| 81 | -- Input | ||
| 82 | -- path | ||
| 83 | -- Returns | ||
| 84 | -- dot-normalized path | ||
| 85 | local function remove_dot_components(path) | ||
| 86 | local marker = string.char(1) | ||
| 87 | repeat | ||
| 88 | local was = path | ||
| 89 | path = path:gsub('//', '/'..marker..'/', 1) | ||
| 90 | until path == was | ||
| 91 | repeat | ||
| 92 | local was = path | ||
| 93 | path = path:gsub('/%./', '/', 1) | ||
| 94 | until path == was | ||
| 95 | repeat | ||
| 96 | local was = path | ||
| 97 | path = path:gsub('[^/]+/%.%./([^/]+)', '%1', 1) | ||
| 98 | until path == was | ||
| 99 | path = path:gsub('[^/]+/%.%./*$', '') | ||
| 100 | path = path:gsub('/%.%.$', '/') | ||
| 101 | path = path:gsub('/%.$', '/') | ||
| 102 | path = path:gsub('^/%.%./', '/') | ||
| 103 | path = path:gsub(marker, '') | ||
| 104 | return path | ||
| 105 | end | ||
| 106 | |||
| 107 | ----------------------------------------------------------------------------- | ||
| 108 | -- Builds a path from a base path and a relative path | 80 | -- Builds a path from a base path and a relative path |
| 109 | -- Input | 81 | -- Input |
| 110 | -- base_path | 82 | -- base_path |
| @@ -113,12 +85,23 @@ end | |||
| 113 | -- corresponding absolute path | 85 | -- corresponding absolute path |
| 114 | ----------------------------------------------------------------------------- | 86 | ----------------------------------------------------------------------------- |
| 115 | local function absolute_path(base_path, relative_path) | 87 | local function absolute_path(base_path, relative_path) |
| 116 | if string.sub(relative_path, 1, 1) == "/" then | 88 | if string.sub(relative_path, 1, 1) == "/" then return relative_path end |
| 117 | return remove_dot_components(relative_path) end | 89 | local path = string.gsub(base_path, "[^/]*$", "") |
| 118 | base_path = base_path:gsub("[^/]*$", "") | 90 | path = path .. relative_path |
| 119 | if not base_path:find'/$' then base_path = base_path .. '/' end | 91 | path = string.gsub(path, "([^/]*%./)", function (s) |
| 120 | local path = base_path .. relative_path | 92 | if s ~= "./" then return s else return "" end |
| 121 | path = remove_dot_components(path) | 93 | end) |
| 94 | path = string.gsub(path, "/%.$", "/") | ||
| 95 | local reduced | ||
| 96 | while reduced ~= path do | ||
| 97 | reduced = path | ||
| 98 | path = string.gsub(reduced, "([^/]*/%.%./)", function (s) | ||
| 99 | if s ~= "../../" then return "" else return s end | ||
| 100 | end) | ||
| 101 | end | ||
| 102 | path = string.gsub(reduced, "([^/]*/%.%.)$", function (s) | ||
| 103 | if s ~= "../.." then return "" else return s end | ||
| 104 | end) | ||
| 122 | return path | 105 | return path |
| 123 | end | 106 | end |
| 124 | 107 | ||
| @@ -244,14 +227,10 @@ function _M.absolute(base_url, relative_url) | |||
| 244 | else | 227 | else |
| 245 | base_parsed = _M.parse(base_url) | 228 | base_parsed = _M.parse(base_url) |
| 246 | end | 229 | end |
| 247 | local result | ||
| 248 | local relative_parsed = _M.parse(relative_url) | 230 | local relative_parsed = _M.parse(relative_url) |
| 249 | if not base_parsed then | 231 | if not base_parsed then return relative_url |
| 250 | result = relative_url | 232 | elseif not relative_parsed then return base_url |
| 251 | elseif not relative_parsed then | 233 | elseif relative_parsed.scheme then return relative_url |
| 252 | result = base_url | ||
| 253 | elseif relative_parsed.scheme then | ||
| 254 | result = relative_url | ||
| 255 | else | 234 | else |
| 256 | relative_parsed.scheme = base_parsed.scheme | 235 | relative_parsed.scheme = base_parsed.scheme |
| 257 | if not relative_parsed.authority then | 236 | if not relative_parsed.authority then |
| @@ -269,9 +248,8 @@ function _M.absolute(base_url, relative_url) | |||
| 269 | relative_parsed.path) | 248 | relative_parsed.path) |
| 270 | end | 249 | end |
| 271 | end | 250 | end |
| 272 | result = _M.build(relative_parsed) | 251 | return _M.build(relative_parsed) |
| 273 | end | 252 | end |
| 274 | return remove_dot_components(result) | ||
| 275 | end | 253 | end |
| 276 | 254 | ||
| 277 | ----------------------------------------------------------------------------- | 255 | ----------------------------------------------------------------------------- |
