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
62
63
|
-- Prosody IM
-- Copyright (C) 2008-2010 Matthew Wild
-- Copyright (C) 2008-2010 Waqas Hussain
--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--
local base64 = require "util.encodings".base64.encode;
local sha1 = require "util.hashes".sha1;
local t_insert, t_sort, t_concat = table.insert, table.sort, table.concat;
local ipairs = ipairs;
local _ENV = nil;
local function calculate_hash(disco_info)
local identities, features, extensions = {}, {}, {};
for _, tag in ipairs(disco_info) do
if tag.name == "identity" then
t_insert(identities, (tag.attr.category or "").."\0"..(tag.attr.type or "").."\0"..(tag.attr["xml:lang"] or "").."\0"..(tag.attr.name or ""));
elseif tag.name == "feature" then
t_insert(features, tag.attr.var or "");
elseif tag.name == "x" and tag.attr.xmlns == "jabber:x:data" then
local form = {};
local FORM_TYPE;
for _, field in ipairs(tag.tags) do
if field.name == "field" and field.attr.var then
local values = {};
for _, val in ipairs(field.tags) do
val = #val.tags == 0 and val:get_text();
if val then t_insert(values, val); end
end
t_sort(values);
if field.attr.var == "FORM_TYPE" then
FORM_TYPE = values[1];
elseif #values > 0 then
t_insert(form, field.attr.var.."\0"..t_concat(values, "<"));
else
t_insert(form, field.attr.var);
end
end
end
t_sort(form);
form = t_concat(form, "<");
if FORM_TYPE then form = FORM_TYPE.."\0"..form; end
t_insert(extensions, form);
end
end
t_sort(identities);
t_sort(features);
t_sort(extensions);
if #identities > 0 then identities = t_concat(identities, "<"):gsub("%z", "/").."<"; else identities = ""; end
if #features > 0 then features = t_concat(features, "<").."<"; else features = ""; end
if #extensions > 0 then extensions = t_concat(extensions, "<"):gsub("%z", "<").."<"; else extensions = ""; end
local S = identities..features..extensions;
local ver = base64(sha1(S));
return ver, S;
end
return {
calculate_hash = calculate_hash;
};
|