Mercurial > prosody-hg
comparison util/xmppstream.lua @ 4797:e239668aa6d2
Merge 0.9->trunk
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Sun, 29 Apr 2012 02:10:55 +0100 |
| parents | 0da4e0f0f0ef |
| children | 86fe6e2fa5ae |
comparison
equal
deleted
inserted
replaced
| 4796:04a34287dc12 | 4797:e239668aa6d2 |
|---|---|
| 9 | 9 |
| 10 local lxp = require "lxp"; | 10 local lxp = require "lxp"; |
| 11 local st = require "util.stanza"; | 11 local st = require "util.stanza"; |
| 12 local stanza_mt = st.stanza_mt; | 12 local stanza_mt = st.stanza_mt; |
| 13 | 13 |
| 14 local error = error; | |
| 14 local tostring = tostring; | 15 local tostring = tostring; |
| 15 local t_insert = table.insert; | 16 local t_insert = table.insert; |
| 16 local t_concat = table.concat; | 17 local t_concat = table.concat; |
| 17 local t_remove = table.remove; | 18 local t_remove = table.remove; |
| 18 local setmetatable = setmetatable; | 19 local setmetatable = setmetatable; |
| 19 | 20 |
| 20 local default_log = require "util.logger".init("xmppstream"); | |
| 21 | |
| 22 -- COMPAT: w/LuaExpat 1.1.0 | 21 -- COMPAT: w/LuaExpat 1.1.0 |
| 23 local lxp_supports_doctype = pcall(lxp.new, { StartDoctypeDecl = false }); | 22 local lxp_supports_doctype = pcall(lxp.new, { StartDoctypeDecl = false }); |
| 24 | |
| 25 if not lxp_supports_doctype then | |
| 26 default_log("warn", "The version of LuaExpat on your system leaves Prosody " | |
| 27 .."vulnerable to denial-of-service attacks. You should upgrade to " | |
| 28 .."LuaExpat 1.1.1 or higher as soon as possible. See " | |
| 29 .."http://prosody.im/doc/depends#luaexpat for more information."); | |
| 30 end | |
| 31 | |
| 32 local error = error; | |
| 33 | 23 |
| 34 module "xmppstream" | 24 module "xmppstream" |
| 35 | 25 |
| 36 local new_parser = lxp.new; | 26 local new_parser = lxp.new; |
| 37 | 27 |
| 38 local ns_prefixes = { | 28 local xml_namespace = { |
| 39 ["http://www.w3.org/XML/1998/namespace"] = "xml"; | 29 ["http://www.w3.org/XML/1998/namespace\1lang"] = "xml:lang"; |
| 30 ["http://www.w3.org/XML/1998/namespace\1space"] = "xml:space"; | |
| 31 ["http://www.w3.org/XML/1998/namespace\1base"] = "xml:base"; | |
| 32 ["http://www.w3.org/XML/1998/namespace\1id"] = "xml:id"; | |
| 40 }; | 33 }; |
| 41 | 34 |
| 42 local xmlns_streams = "http://etherx.jabber.org/streams"; | 35 local xmlns_streams = "http://etherx.jabber.org/streams"; |
| 43 | 36 |
| 44 local ns_separator = "\1"; | 37 local ns_separator = "\1"; |
| 47 _M.ns_separator = ns_separator; | 40 _M.ns_separator = ns_separator; |
| 48 _M.ns_pattern = ns_pattern; | 41 _M.ns_pattern = ns_pattern; |
| 49 | 42 |
| 50 function new_sax_handlers(session, stream_callbacks) | 43 function new_sax_handlers(session, stream_callbacks) |
| 51 local xml_handlers = {}; | 44 local xml_handlers = {}; |
| 52 | |
| 53 local log = session.log or default_log; | |
| 54 | 45 |
| 55 local cb_streamopened = stream_callbacks.streamopened; | 46 local cb_streamopened = stream_callbacks.streamopened; |
| 56 local cb_streamclosed = stream_callbacks.streamclosed; | 47 local cb_streamclosed = stream_callbacks.streamclosed; |
| 57 local cb_error = stream_callbacks.error or function(session, e) error("XML stream error: "..tostring(e)); end; | 48 local cb_error = stream_callbacks.error or function(session, e) error("XML stream error: "..tostring(e)); end; |
| 58 local cb_handlestanza = stream_callbacks.handlestanza; | 49 local cb_handlestanza = stream_callbacks.handlestanza; |
| 83 if curr_ns ~= stream_default_ns or non_streamns_depth > 0 then | 74 if curr_ns ~= stream_default_ns or non_streamns_depth > 0 then |
| 84 attr.xmlns = curr_ns; | 75 attr.xmlns = curr_ns; |
| 85 non_streamns_depth = non_streamns_depth + 1; | 76 non_streamns_depth = non_streamns_depth + 1; |
| 86 end | 77 end |
| 87 | 78 |
| 88 -- FIXME !!!!! | |
| 89 for i=1,#attr do | 79 for i=1,#attr do |
| 90 local k = attr[i]; | 80 local k = attr[i]; |
| 91 attr[i] = nil; | 81 attr[i] = nil; |
| 92 local ns, nm = k:match(ns_pattern); | 82 local xmlk = xml_namespace[k]; |
| 93 if nm ~= "" then | 83 if xmlk then |
| 94 ns = ns_prefixes[ns]; | 84 attr[xmlk] = attr[k]; |
| 95 if ns then | 85 attr[k] = nil; |
| 96 attr[ns..":"..nm] = attr[k]; | |
| 97 attr[k] = nil; | |
| 98 end | |
| 99 end | 86 end |
| 100 end | 87 end |
| 101 | 88 |
| 102 if not stanza then --if we are not currently inside a stanza | 89 if not stanza then --if we are not currently inside a stanza |
| 103 if session.notopen then | 90 if session.notopen then |
| 150 stanza = nil; | 137 stanza = nil; |
| 151 else | 138 else |
| 152 stanza = t_remove(stack); | 139 stanza = t_remove(stack); |
| 153 end | 140 end |
| 154 else | 141 else |
| 155 if tagname == stream_tag then | 142 if cb_streamclosed then |
| 156 if cb_streamclosed then | 143 cb_streamclosed(session); |
| 157 cb_streamclosed(session); | |
| 158 end | |
| 159 else | |
| 160 local curr_ns,name = tagname:match(ns_pattern); | |
| 161 if name == "" then | |
| 162 curr_ns, name = "", curr_ns; | |
| 163 end | |
| 164 cb_error(session, "parse-error", "unexpected-element-close", name); | |
| 165 end | 144 end |
| 166 stanza, chardata = nil, {}; | |
| 167 stack = {}; | |
| 168 end | 145 end |
| 169 end | 146 end |
| 170 | 147 |
| 171 local function restricted_handler(parser) | 148 local function restricted_handler(parser) |
| 172 cb_error(session, "parse-error", "restricted-xml", "Restricted XML, see RFC 6120 section 11.1."); | 149 cb_error(session, "parse-error", "restricted-xml", "Restricted XML, see RFC 6120 section 11.1."); |
| 186 stack = {}; | 163 stack = {}; |
| 187 end | 164 end |
| 188 | 165 |
| 189 local function set_session(stream, new_session) | 166 local function set_session(stream, new_session) |
| 190 session = new_session; | 167 session = new_session; |
| 191 log = new_session.log or default_log; | |
| 192 end | 168 end |
| 193 | 169 |
| 194 return xml_handlers, { reset = reset, set_session = set_session }; | 170 return xml_handlers, { reset = reset, set_session = set_session }; |
| 195 end | 171 end |
| 196 | 172 |
