core/xmlhandlers.lua
changeset 5 57e4eb3aeac0
child 7 dcc5ac721c20
equal deleted inserted replaced
-1:000000000000 5:57e4eb3aeac0
       
     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;