Mercurial > prosody-hg
comparison util/stanza.lua @ 10411:db2a06b9ff98
Merge 0.11->trunk
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Sat, 16 Nov 2019 16:52:31 +0100 |
| parents | 4807535b8673 |
| children | 22db763c510c |
comparison
equal
deleted
inserted
replaced
| 10410:659b577f280c | 10411:db2a06b9ff98 |
|---|---|
| 96 function stanza_mt:query(xmlns) | 96 function stanza_mt:query(xmlns) |
| 97 return self:tag("query", { xmlns = xmlns }); | 97 return self:tag("query", { xmlns = xmlns }); |
| 98 end | 98 end |
| 99 | 99 |
| 100 function stanza_mt:body(text, attr) | 100 function stanza_mt:body(text, attr) |
| 101 return self:tag("body", attr):text(text); | 101 return self:text_tag("body", text, attr); |
| 102 end | 102 end |
| 103 | 103 |
| 104 function stanza_mt:text_tag(name, text, attr, namespaces) | 104 function stanza_mt:text_tag(name, text, attr, namespaces) |
| 105 return self:tag(name, attr, namespaces):text(text):up(); | 105 return self:tag(name, attr, namespaces):text(text):up(); |
| 106 end | 106 end |
| 268 end | 268 end |
| 269 self = self:get_child(name, xmlns); | 269 self = self:get_child(name, xmlns); |
| 270 until not self | 270 until not self |
| 271 end | 271 end |
| 272 | 272 |
| 273 local function _clone(stanza, only_top) | |
| 274 local attr, tags = {}, {}; | |
| 275 for k,v in pairs(stanza.attr) do attr[k] = v; end | |
| 276 local old_namespaces, namespaces = stanza.namespaces; | |
| 277 if old_namespaces then | |
| 278 namespaces = {}; | |
| 279 for k,v in pairs(old_namespaces) do namespaces[k] = v; end | |
| 280 end | |
| 281 local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags }; | |
| 282 if not only_top then | |
| 283 for i=1,#stanza do | |
| 284 local child = stanza[i]; | |
| 285 if child.name then | |
| 286 child = _clone(child); | |
| 287 t_insert(tags, child); | |
| 288 end | |
| 289 t_insert(new, child); | |
| 290 end | |
| 291 end | |
| 292 return setmetatable(new, stanza_mt); | |
| 293 end | |
| 294 | |
| 295 local function clone(stanza, only_top) | |
| 296 if not is_stanza(stanza) then | |
| 297 error("bad argument to clone: expected stanza, got "..type(stanza)); | |
| 298 end | |
| 299 return _clone(stanza, only_top); | |
| 300 end | |
| 273 | 301 |
| 274 local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; | 302 local escape_table = { ["'"] = "'", ["\""] = """, ["<"] = "<", [">"] = ">", ["&"] = "&" }; |
| 275 local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end | 303 local function xml_escape(str) return (s_gsub(str, "['&<>\"]", escape_table)); end |
| 276 | 304 |
| 277 local function _dostring(t, buf, self, _xml_escape, parentns) | 305 local function _dostring(t, buf, self, _xml_escape, parentns) |
| 308 _dostring(t, buf, _dostring, xml_escape, nil); | 336 _dostring(t, buf, _dostring, xml_escape, nil); |
| 309 return t_concat(buf); | 337 return t_concat(buf); |
| 310 end | 338 end |
| 311 | 339 |
| 312 function stanza_mt.top_tag(t) | 340 function stanza_mt.top_tag(t) |
| 313 local attr_string = ""; | 341 local top_tag_clone = clone(t, true); |
| 314 if t.attr then | 342 return tostring(top_tag_clone):sub(1,-3)..">"; |
| 315 for k, v in pairs(t.attr) do if type(k) == "string" then attr_string = attr_string .. s_format(" %s='%s'", k, xml_escape(tostring(v))); end end | |
| 316 end | |
| 317 return s_format("<%s%s>", t.name, attr_string); | |
| 318 end | 343 end |
| 319 | 344 |
| 320 function stanza_mt.get_text(t) | 345 function stanza_mt.get_text(t) |
| 321 if #t.tags == 0 then | 346 if #t.tags == 0 then |
| 322 return t_concat(t); | 347 return t_concat(t); |
| 386 end | 411 end |
| 387 return stanza; | 412 return stanza; |
| 388 end | 413 end |
| 389 end | 414 end |
| 390 | 415 |
| 391 local function _clone(stanza) | |
| 392 local attr, tags = {}, {}; | |
| 393 for k,v in pairs(stanza.attr) do attr[k] = v; end | |
| 394 local old_namespaces, namespaces = stanza.namespaces; | |
| 395 if old_namespaces then | |
| 396 namespaces = {}; | |
| 397 for k,v in pairs(old_namespaces) do namespaces[k] = v; end | |
| 398 end | |
| 399 local new = { name = stanza.name, attr = attr, namespaces = namespaces, tags = tags }; | |
| 400 for i=1,#stanza do | |
| 401 local child = stanza[i]; | |
| 402 if child.name then | |
| 403 child = _clone(child); | |
| 404 t_insert(tags, child); | |
| 405 end | |
| 406 t_insert(new, child); | |
| 407 end | |
| 408 return setmetatable(new, stanza_mt); | |
| 409 end | |
| 410 | |
| 411 local function clone(stanza) | |
| 412 if not is_stanza(stanza) then | |
| 413 error("bad argument to clone: expected stanza, got "..type(stanza)); | |
| 414 end | |
| 415 return _clone(stanza); | |
| 416 end | |
| 417 | |
| 418 local function message(attr, body) | 416 local function message(attr, body) |
| 419 if not body then | 417 if not body then |
| 420 return new_stanza("message", attr); | 418 return new_stanza("message", attr); |
| 421 else | 419 else |
| 422 return new_stanza("message", attr):tag("body"):text(body):up(); | 420 return new_stanza("message", attr):text_tag("body", body); |
| 423 end | 421 end |
| 424 end | 422 end |
| 425 local function iq(attr) | 423 local function iq(attr) |
| 426 if not (attr and attr.id) then | 424 if not attr then |
| 425 error("iq stanzas require id and type attributes"); | |
| 426 end | |
| 427 if not attr.id then | |
| 427 error("iq stanzas require an id attribute"); | 428 error("iq stanzas require an id attribute"); |
| 429 end | |
| 430 if not attr.type then | |
| 431 error("iq stanzas require a type attribute"); | |
| 428 end | 432 end |
| 429 return new_stanza("iq", attr); | 433 return new_stanza("iq", attr); |
| 430 end | 434 end |
| 431 | 435 |
| 432 local function reply(orig) | 436 local function reply(orig) |
| 443 local function error_reply(orig, error_type, condition, error_message) | 447 local function error_reply(orig, error_type, condition, error_message) |
| 444 local t = reply(orig); | 448 local t = reply(orig); |
| 445 t.attr.type = "error"; | 449 t.attr.type = "error"; |
| 446 t:tag("error", {type = error_type}) --COMPAT: Some day xmlns:stanzas goes here | 450 t:tag("error", {type = error_type}) --COMPAT: Some day xmlns:stanzas goes here |
| 447 :tag(condition, xmpp_stanzas_attr):up(); | 451 :tag(condition, xmpp_stanzas_attr):up(); |
| 448 if error_message then t:tag("text", xmpp_stanzas_attr):text(error_message):up(); end | 452 if error_message then t:text_tag("text", error_message, xmpp_stanzas_attr); end |
| 449 return t; -- stanza ready for adding app-specific errors | 453 return t; -- stanza ready for adding app-specific errors |
| 450 end | 454 end |
| 451 | 455 |
| 452 local function presence(attr) | 456 local function presence(attr) |
| 453 return new_stanza("presence", attr); | 457 return new_stanza("presence", attr); |
