Comparison

core/xmlhandlers.lua @ 1:b8787e859fd2

Switched to new connection framework, courtesy of the luadch project Now supports SSL on 5223 Beginning support for presence (aka. the proper routing of stanzas)
author matthew
date Sun, 24 Aug 2008 01:51:02 +0000
child 7:dcc5ac721c20
comparison
equal deleted inserted replaced
0:3e3171b59028 1:b8787e859fd2
1
2 require "util.stanza"
3
4 local st = stanza;
5 local tostring = tostring;
6 local format = string.format;
7 local m_random = math.random;
8 local t_insert = table.insert;
9 local t_remove = table.remove;
10 local t_concat = table.concat;
11 local t_concatall = function (t, sep) local tt = {}; for _, s in ipairs(t) do t_insert(tt, tostring(s)); end return t_concat(tt, sep); end
12
13 local error = error;
14
15 module "xmlhandlers"
16
17 function init_xmlhandlers(session)
18 local ns_stack = { "" };
19 local curr_ns = "";
20 local curr_tag;
21 local chardata = {};
22 local xml_handlers = {};
23 local log = session.log;
24 local print = function (...) log("info", "xmlhandlers", t_concatall({...}, "\t")); end
25
26 local send = session.send;
27
28 local stanza
29 function xml_handlers:StartElement(name, attr)
30 if stanza and #chardata > 0 then
31 stanza:text(t_concat(chardata));
32 print("Char data:", t_concat(chardata));
33 chardata = {};
34 end
35 curr_ns,name = name:match("^(.+):(%w+)$");
36 print("Tag received:", name, tostring(curr_ns));
37 if not stanza then
38 if session.notopen then
39 if name == "stream" then
40 session.host = attr.to or error("Client failed to specify destination hostname");
41 session.version = attr.version or 0;
42 session.streamid = m_random(1000000, 99999999);
43 print(session, session.host, "Client opened stream");
44 send("<?xml version='1.0'?>");
45 send(format("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='%s' from='%s' >", session.streamid, session.host));
46 --send("<stream:features>");
47 --send("<mechanism>PLAIN</mechanism>");
48 --send [[<register xmlns="http://jabber.org/features/iq-register"/> ]]
49 --send("</stream:features>");
50 log("info", "core", "Stream opened successfully");
51 session.notopen = nil;
52 return;
53 end
54 error("Client failed to open stream successfully");
55 end
56 if name ~= "iq" and name ~= "presence" and name ~= "message" then
57 error("Client sent invalid top-level stanza");
58 end
59 stanza = st.stanza(name, { to = attr.to, type = attr.type, id = attr.id, xmlns = curr_ns });
60 curr_tag = stanza;
61 else
62 attr.xmlns = curr_ns;
63 stanza:tag(name, attr);
64 end
65 end
66 function xml_handlers:CharacterData(data)
67 if stanza then
68 t_insert(chardata, data);
69 end
70 end
71 function xml_handlers:EndElement(name)
72 curr_ns,name = name:match("^(.+):(%w+)$");
73 --print("<"..name.."/>", tostring(stanza), tostring(#stanza.last_add < 1), tostring(stanza.last_add[#stanza.last_add].name));
74 if (not stanza) or #stanza.last_add < 0 or (#stanza.last_add > 0 and name ~= stanza.last_add[#stanza.last_add].name) then error("XML parse error in client stream"); end
75 if stanza and #chardata > 0 then
76 stanza:text(t_concat(chardata));
77 print("Char data:", t_concat(chardata));
78 chardata = {};
79 end
80 -- Complete stanza
81 print(name, tostring(#stanza.last_add));
82 if #stanza.last_add == 0 then
83 session.stanza_dispatch(stanza);
84 stanza = nil;
85 else
86 stanza:up();
87 end
88 end
89 return xml_handlers;
90 end
91
92 return init_xmlhandlers;