summaryrefslogtreecommitdiff
path: root/server/src/uri.lua
blob: a9b64177233849e944d5645fbd089b73601243c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
local fs = require 'bee.filesystem'
local platform = require 'bee.platform'

local function decode(uri)
    -- Unix-like系统根是/
    if uri:sub(1, 9) == 'file:////' then
        return fs.path(uri:sub(9))
    end
    if uri:sub(1, 8) ~= 'file:///' then
        log.error('uri decode failed: ', uri)
        return nil
    end

    -- linux uri example: file:///home/user/project/
    if platform.OS == 'Linux' then
        return fs.path(uri:sub(8))
    end
   
    local names = {}
    for name in uri:sub(9):gmatch '[^%/]+' do
        names[#names+1] = name:gsub('%%([0-9a-fA-F][0-9a-fA-F])', function (hex)
            return string.char(tonumber(hex, 16))
        end)
    end
    if #names == 0 then
        log.error('uri decode failed: ', uri)
        return nil
    end
    -- 盘符后面加个斜杠
    local path = fs.path(names[1] .. '/')
    for i = 2, #names do
        path = path / names[i]
    end
    return fs.absolute(path)
end

local function encode(path)
    local names = {}
    local cur = fs.absolute(path)
    while true do
        local name = cur:filename():string()
        if name == '' then
            -- 盘符,去掉一个斜杠
            name = cur:string():sub(1, -2)
        end
        name = name:gsub([=[[^%w%-%_%.%~]]=], function (char)
            return ('%%%02X'):format(string.byte(char))
        end)
        table.insert(names, 1, name)
        if cur == cur:parent_path() then
            break
        end
        cur = cur:parent_path()
    end
    return 'file:///' .. table.concat(names, '/')
end

return {
    encode = encode,
    decode = decode,
}