util/caps.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
local base64 = require "util.encodings".base64.encode;
10
local sha1 = require "util.hashes".sha1;
11
 
12
local t_insert, t_sort, t_concat = table.insert, table.sort, table.concat;
13
local ipairs = ipairs;
14
 
15
module "caps"
16
 
17
function calculate_hash(disco_info)
18
	local identities, features, extensions = {}, {}, {};
19
	for _, tag in ipairs(disco_info) do
20
		if tag.name == "identity" then
21
			t_insert(identities, (tag.attr.category or "").."\0"..(tag.attr.type or "").."\0"..(tag.attr["xml:lang"] or "").."\0"..(tag.attr.name or ""));
22
		elseif tag.name == "feature" then
23
			t_insert(features, tag.attr.var or "");
24
		elseif tag.name == "x" and tag.attr.xmlns == "jabber:x:data" then
25
			local form = {};
26
			local FORM_TYPE;
27
			for _, field in ipairs(tag.tags) do
28
				if field.name == "field" and field.attr.var then
29
					local values = {};
30
					for _, val in ipairs(field.tags) do
31
						val = #val.tags == 0 and val:get_text();
32
						if val then t_insert(values, val); end
33
					end
34
					t_sort(values);
35
					if field.attr.var == "FORM_TYPE" then
36
						FORM_TYPE = values[1];
37
					elseif #values > 0 then
38
						t_insert(form, field.attr.var.."\0"..t_concat(values, "<"));
39
					else
40
						t_insert(form, field.attr.var);
41
					end
42
				end
43
			end
44
			t_sort(form);
45
			form = t_concat(form, "<");
46
			if FORM_TYPE then form = FORM_TYPE.."\0"..form; end
47
			t_insert(extensions, form);
48
		end
49
	end
50
	t_sort(identities);
51
	t_sort(features);
52
	t_sort(extensions);
53
	if #identities > 0 then identities = t_concat(identities, "<"):gsub("%z", "/").."<"; else identities = ""; end
54
	if #features > 0 then features = t_concat(features, "<").."<"; else features = ""; end
55
	if #extensions > 0 then extensions = t_concat(extensions, "<"):gsub("%z", "<").."<"; else extensions = ""; end
56
	local S = identities..features..extensions;
57
	local ver = base64(sha1(S));
58
	return ver, S;
59
end
60
 
61
return _M;