Merge 0.9->0.10
[prosody.git] / util / jid.lua
1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
4 --
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9
10
11 local match = string.match;
12 local nodeprep = require "util.encodings".stringprep.nodeprep;
13 local nameprep = require "util.encodings".stringprep.nameprep;
14 local resourceprep = require "util.encodings".stringprep.resourceprep;
15
16 local escapes = {
17         [" "] = "\\20"; ['"'] = "\\22";
18         ["&"] = "\\26"; ["'"] = "\\27";
19         ["/"] = "\\2f"; [":"] = "\\3a";
20         ["<"] = "\\3c"; [">"] = "\\3e";
21         ["@"] = "\\40"; ["\\"] = "\\5c";
22 };
23 local unescapes = {};
24 for k,v in pairs(escapes) do unescapes[v] = k; end
25
26 module "jid"
27
28 local function _split(jid)
29         if not jid then return; end
30         local node, nodepos = match(jid, "^([^@/]+)@()");
31         local host, hostpos = match(jid, "^([^@/]+)()", nodepos)
32         if node and not host then return nil, nil, nil; end
33         local resource = match(jid, "^/(.+)$", hostpos);
34         if (not host) or ((not resource) and #jid >= hostpos) then return nil, nil, nil; end
35         return node, host, resource;
36 end
37 split = _split;
38
39 function bare(jid)
40         local node, host = _split(jid);
41         if node and host then
42                 return node.."@"..host;
43         end
44         return host;
45 end
46
47 local function _prepped_split(jid)
48         local node, host, resource = _split(jid);
49         if host then
50                 host = nameprep(host);
51                 if not host then return; end
52                 if node then
53                         node = nodeprep(node);
54                         if not node then return; end
55                 end
56                 if resource then
57                         resource = resourceprep(resource);
58                         if not resource then return; end
59                 end
60                 return node, host, resource;
61         end
62 end
63 prepped_split = _prepped_split;
64
65 function prep(jid)
66         local node, host, resource = _prepped_split(jid);
67         if host then
68                 if node then
69                         host = node .. "@" .. host;
70                 end
71                 if resource then
72                         host = host .. "/" .. resource;
73                 end
74         end
75         return host;
76 end
77
78 function join(node, host, resource)
79         if node and host and resource then
80                 return node.."@"..host.."/"..resource;
81         elseif node and host then
82                 return node.."@"..host;
83         elseif host and resource then
84                 return host.."/"..resource;
85         elseif host then
86                 return host;
87         end
88         return nil; -- Invalid JID
89 end
90
91 function compare(jid, acl)
92         -- compare jid to single acl rule
93         -- TODO compare to table of rules?
94         local jid_node, jid_host, jid_resource = _split(jid);
95         local acl_node, acl_host, acl_resource = _split(acl);
96         if ((acl_node ~= nil and acl_node == jid_node) or acl_node == nil) and
97                 ((acl_host ~= nil and acl_host == jid_host) or acl_host == nil) and
98                 ((acl_resource ~= nil and acl_resource == jid_resource) or acl_resource == nil) then
99                 return true
100         end
101         return false
102 end
103
104 function escape(s) return s and (s:gsub(".", escapes)); end
105 function unescape(s) return s and (s:gsub("\\%x%x", unescapes)); end
106
107 return _M;