diff options
Diffstat (limited to 'src/url.lua')
-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 | ----------------------------------------------------------------------------- |