Software /
code /
prosody
Annotate
spec/util_datamapper_spec.lua @ 13652:a08065207ef0
net.server_epoll: Call :shutdown() on TLS sockets when supported
Comment from Matthew:
This fixes a potential issue where the Prosody process gets blocked on sockets
waiting for them to close. Unlike non-TLS sockets, closing a TLS socket sends
layer 7 data, and this can cause problems for sockets which are in the process
of being cleaned up.
This depends on LuaSec changes which are not yet upstream.
From Martijn's original email:
So first my analysis of luasec. in ssl.c the socket is put into blocking
mode right before calling SSL_shutdown() inside meth_destroy(). My best
guess to why this is is because meth_destroy is linked to the __close
and __gc methods, which can't exactly be called multiple times and
luasec does want to make sure that a tls session is shutdown as clean
as possible.
I can't say I disagree with this reasoning and don't want to change this
behaviour. My solution to this without changing the current behaviour is
to introduce a shutdown() method. I am aware that this overlaps in a
conflicting way with tcp's shutdown method, but it stays close to the
OpenSSL name. This method calls SSL_shutdown() in the current
(non)blocking mode of the underlying socket and returns a boolean
whether or not the shutdown is completed (matching SSL_shutdown()'s 0
or 1 return values), and returns the familiar ssl_ioerror() strings on
error with a false for completion. This error can then be used to
determine if we have wantread/wantwrite to finalize things. Once
meth_shutdown() has been called once a shutdown flag will be set, which
indicates to meth_destroy() that the SSL_shutdown() has been handled
by the application and it shouldn't be needed to set the socket to
blocking mode. I've left the SSL_shutdown() call in the
LSEC_STATE_CONNECTED to prevent TOCTOU if the application reaches a
timeout for the shutdown code, which might allow SSL_shutdown() to
clean up anyway at the last possible moment.
Another thing I've changed to luasec is the call to socket_setblocking()
right before calling close(2) in socket_destroy() in usocket.c.
According to the latest POSIX[0]:
Note that the requirement for close() on a socket to block for up to
the current linger interval is not conditional on the O_NONBLOCK
setting.
Which I read to mean that removing O_NONBLOCK on the socket before close
doesn't impact the behaviour and only causes noise in system call
tracers. I didn't touch the windows bits of this, since I don't do
windows.
For the prosody side of things I've made the TLS shutdown bits resemble
interface:onwritable(), and put it under a combined guard of self._tls
and self.conn.shutdown. The self._tls bit is there to prevent getting
stuck on this condition, and self.conn.shutdown is there to prevent the
code being called by instances where the patched luasec isn't deployed.
The destroy() method can be called from various places and is read by
me as the "we give up" error path. To accommodate for these unexpected
entrypoints I've added a single call to self.conn:shutdown() to prevent
the socket being put into blocking mode. I have no expectations that
there is any other use here. Same as previous, the self.conn.shutdown
check is there to make sure it's not called on unpatched luasec
deployments and self._tls is there to make sure we don't call shutdown()
on tcp sockets.
I wouldn't recommend logging of the conn:shutdown() error inside
close(), since a lot of clients simply close the connection before
SSL_shutdown() is done.
author | Martijn van Duren <martijn@openbsd.org> |
---|---|
date | Thu, 06 Feb 2025 15:04:38 +0000 |
parent | 12818:74ed772ff5fb |
rev | line source |
---|---|
11476
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
1 local st |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
2 local xml |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
3 local map |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
4 |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
5 setup(function() |
11476
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
6 st = require "util.stanza"; |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
7 xml = require "util.xml"; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
8 map = require "util.datamapper"; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
9 end); |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
10 |
12134
912614c4bf3e
util_datamapper: Fix typo in unit tests
Kim Alvefur <zash@zash.se>
parents:
12133
diff
changeset
|
11 describe("util.datamapper", function() |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
12 |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
13 local s, x, d |
11466
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
14 local disco, disco_info, disco_schema |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
15 setup(function() |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
16 |
11487
b104c10ffce7
util.datamapper: Use attribute convenience function throughout
Kim Alvefur <zash@zash.se>
parents:
11480
diff
changeset
|
17 -- a convenience function for simple attributes, there's a few of them |
12818
74ed772ff5fb
util.datamapper: Simplify test schema
Kim Alvefur <zash@zash.se>
parents:
12580
diff
changeset
|
18 local attr = {["$ref"]="#/$defs/attr"}; |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
19 s = { |
12133
11060c8919b6
util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents:
11494
diff
changeset
|
20 ["$defs"] = { attr = { type = "string"; xml = { attribute = true } } }; |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
21 type = "object"; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
22 xml = {name = "message"; namespace = "jabber:client"}; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
23 properties = { |
12818
74ed772ff5fb
util.datamapper: Simplify test schema
Kim Alvefur <zash@zash.se>
parents:
12580
diff
changeset
|
24 to = attr; |
74ed772ff5fb
util.datamapper: Simplify test schema
Kim Alvefur <zash@zash.se>
parents:
12580
diff
changeset
|
25 from = attr; |
74ed772ff5fb
util.datamapper: Simplify test schema
Kim Alvefur <zash@zash.se>
parents:
12580
diff
changeset
|
26 type = attr; |
74ed772ff5fb
util.datamapper: Simplify test schema
Kim Alvefur <zash@zash.se>
parents:
12580
diff
changeset
|
27 id = attr; |
12580
a9dbf657c894
util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents:
12134
diff
changeset
|
28 body = true; -- should be assumed to be a string |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
29 lang = {type = "string"; xml = {attribute = true; prefix = "xml"}}; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
30 delay = { |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
31 type = "object"; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
32 xml = {namespace = "urn:xmpp:delay"; name = "delay"}; |
12818
74ed772ff5fb
util.datamapper: Simplify test schema
Kim Alvefur <zash@zash.se>
parents:
12580
diff
changeset
|
33 properties = {stamp = attr; from = attr; reason = {type = "string"; xml = {text = true}}}; |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
34 }; |
11437
87a684df4b65
util.datamapper: Invent extension for using tag name as value
Kim Alvefur <zash@zash.se>
parents:
11436
diff
changeset
|
35 state = { |
87a684df4b65
util.datamapper: Invent extension for using tag name as value
Kim Alvefur <zash@zash.se>
parents:
11436
diff
changeset
|
36 type = "string"; |
11453
f0037234b2e9
util.datamapper: Enumerated elements
Kim Alvefur <zash@zash.se>
parents:
11439
diff
changeset
|
37 enum = { |
f0037234b2e9
util.datamapper: Enumerated elements
Kim Alvefur <zash@zash.se>
parents:
11439
diff
changeset
|
38 "active", |
f0037234b2e9
util.datamapper: Enumerated elements
Kim Alvefur <zash@zash.se>
parents:
11439
diff
changeset
|
39 "inactive", |
f0037234b2e9
util.datamapper: Enumerated elements
Kim Alvefur <zash@zash.se>
parents:
11439
diff
changeset
|
40 "gone", |
f0037234b2e9
util.datamapper: Enumerated elements
Kim Alvefur <zash@zash.se>
parents:
11439
diff
changeset
|
41 "composing", |
f0037234b2e9
util.datamapper: Enumerated elements
Kim Alvefur <zash@zash.se>
parents:
11439
diff
changeset
|
42 "paused", |
f0037234b2e9
util.datamapper: Enumerated elements
Kim Alvefur <zash@zash.se>
parents:
11439
diff
changeset
|
43 }; |
11437
87a684df4b65
util.datamapper: Invent extension for using tag name as value
Kim Alvefur <zash@zash.se>
parents:
11436
diff
changeset
|
44 xml = {x_name_is_value = true; namespace = "http://jabber.org/protocol/chatstates"}; |
87a684df4b65
util.datamapper: Invent extension for using tag name as value
Kim Alvefur <zash@zash.se>
parents:
11436
diff
changeset
|
45 }; |
11438
b7807583de34
util.datamapper: Add logic for "boolean" tags here the presence means true
Kim Alvefur <zash@zash.se>
parents:
11437
diff
changeset
|
46 fallback = { |
b7807583de34
util.datamapper: Add logic for "boolean" tags here the presence means true
Kim Alvefur <zash@zash.se>
parents:
11437
diff
changeset
|
47 type = "boolean"; |
b7807583de34
util.datamapper: Add logic for "boolean" tags here the presence means true
Kim Alvefur <zash@zash.se>
parents:
11437
diff
changeset
|
48 xml = {x_name_is_value = true; name = "fallback"; namespace = "urn:xmpp:fallback:0"}; |
b7807583de34
util.datamapper: Add logic for "boolean" tags here the presence means true
Kim Alvefur <zash@zash.se>
parents:
11437
diff
changeset
|
49 }; |
11439
9abcdfdcdb01
util.datamapper: Add support for mapping of elements where only one attribute matters
Kim Alvefur <zash@zash.se>
parents:
11438
diff
changeset
|
50 origin_id = { |
9abcdfdcdb01
util.datamapper: Add support for mapping of elements where only one attribute matters
Kim Alvefur <zash@zash.se>
parents:
11438
diff
changeset
|
51 type = "string"; |
9abcdfdcdb01
util.datamapper: Add support for mapping of elements where only one attribute matters
Kim Alvefur <zash@zash.se>
parents:
11438
diff
changeset
|
52 xml = {name = "origin-id"; namespace = "urn:xmpp:sid:0"; x_single_attribute = "id"}; |
9abcdfdcdb01
util.datamapper: Add support for mapping of elements where only one attribute matters
Kim Alvefur <zash@zash.se>
parents:
11438
diff
changeset
|
53 }; |
11462
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
54 react = { |
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
55 type = "object"; |
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
56 xml = {namespace = "urn:xmpp:reactions:0"; name = "reactions"}; |
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
57 properties = { |
11488
332c9291f4d5
util.datamapper: Revert one special attribute to longer form
Kim Alvefur <zash@zash.se>
parents:
11487
diff
changeset
|
58 to = {type = "string"; xml = {attribute = true; name = "id"}}; |
12580
a9dbf657c894
util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents:
12134
diff
changeset
|
59 -- should be assumed to be array since it has 'items' |
a9dbf657c894
util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents:
12134
diff
changeset
|
60 reactions = { items = { xml = { name = "reaction" } } }; |
11462
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
61 }; |
11457
6a51749af7f4
util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11453
diff
changeset
|
62 }; |
11480
0aa2971380e9
util.datamapper: Add test coverage of unwrapped arrays of objects
Kim Alvefur <zash@zash.se>
parents:
11476
diff
changeset
|
63 stanza_ids = { |
0aa2971380e9
util.datamapper: Add test coverage of unwrapped arrays of objects
Kim Alvefur <zash@zash.se>
parents:
11476
diff
changeset
|
64 type = "array"; |
0aa2971380e9
util.datamapper: Add test coverage of unwrapped arrays of objects
Kim Alvefur <zash@zash.se>
parents:
11476
diff
changeset
|
65 items = { |
0aa2971380e9
util.datamapper: Add test coverage of unwrapped arrays of objects
Kim Alvefur <zash@zash.se>
parents:
11476
diff
changeset
|
66 xml = {name = "stanza-id"; namespace = "urn:xmpp:sid:0"}; |
0aa2971380e9
util.datamapper: Add test coverage of unwrapped arrays of objects
Kim Alvefur <zash@zash.se>
parents:
11476
diff
changeset
|
67 type = "object"; |
0aa2971380e9
util.datamapper: Add test coverage of unwrapped arrays of objects
Kim Alvefur <zash@zash.se>
parents:
11476
diff
changeset
|
68 properties = { |
12818
74ed772ff5fb
util.datamapper: Simplify test schema
Kim Alvefur <zash@zash.se>
parents:
12580
diff
changeset
|
69 id = attr; |
74ed772ff5fb
util.datamapper: Simplify test schema
Kim Alvefur <zash@zash.se>
parents:
12580
diff
changeset
|
70 by = attr; |
11480
0aa2971380e9
util.datamapper: Add test coverage of unwrapped arrays of objects
Kim Alvefur <zash@zash.se>
parents:
11476
diff
changeset
|
71 }; |
0aa2971380e9
util.datamapper: Add test coverage of unwrapped arrays of objects
Kim Alvefur <zash@zash.se>
parents:
11476
diff
changeset
|
72 }; |
0aa2971380e9
util.datamapper: Add test coverage of unwrapped arrays of objects
Kim Alvefur <zash@zash.se>
parents:
11476
diff
changeset
|
73 }; |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
74 }; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
75 }; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
76 |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
77 x = xml.parse [[ |
11437
87a684df4b65
util.datamapper: Invent extension for using tag name as value
Kim Alvefur <zash@zash.se>
parents:
11436
diff
changeset
|
78 <message xmlns="jabber:client" xml:lang="en" to="a@test" from="b@test" type="chat" id="1"> |
87a684df4b65
util.datamapper: Invent extension for using tag name as value
Kim Alvefur <zash@zash.se>
parents:
11436
diff
changeset
|
79 <body>Hello</body> |
11494
284c822d4c3d
util.datamapper: Fix spelling in tests
Kim Alvefur <zash@zash.se>
parents:
11488
diff
changeset
|
80 <delay xmlns='urn:xmpp:delay' from='test' stamp='2021-03-07T15:59:08+00:00'>Because</delay> |
11453
f0037234b2e9
util.datamapper: Enumerated elements
Kim Alvefur <zash@zash.se>
parents:
11439
diff
changeset
|
81 <UNRELATED xmlns='http://jabber.org/protocol/chatstates'/> |
11437
87a684df4b65
util.datamapper: Invent extension for using tag name as value
Kim Alvefur <zash@zash.se>
parents:
11436
diff
changeset
|
82 <active xmlns='http://jabber.org/protocol/chatstates'/> |
11438
b7807583de34
util.datamapper: Add logic for "boolean" tags here the presence means true
Kim Alvefur <zash@zash.se>
parents:
11437
diff
changeset
|
83 <fallback xmlns='urn:xmpp:fallback:0'/> |
11439
9abcdfdcdb01
util.datamapper: Add support for mapping of elements where only one attribute matters
Kim Alvefur <zash@zash.se>
parents:
11438
diff
changeset
|
84 <origin-id xmlns='urn:xmpp:sid:0' id='qgkmMdPB'/> |
11480
0aa2971380e9
util.datamapper: Add test coverage of unwrapped arrays of objects
Kim Alvefur <zash@zash.se>
parents:
11476
diff
changeset
|
85 <stanza-id xmlns='urn:xmpp:sid:0' id='abc1' by='muc'/> |
0aa2971380e9
util.datamapper: Add test coverage of unwrapped arrays of objects
Kim Alvefur <zash@zash.se>
parents:
11476
diff
changeset
|
86 <stanza-id xmlns='urn:xmpp:sid:0' id='xyz2' by='host'/> |
11457
6a51749af7f4
util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11453
diff
changeset
|
87 <reactions id='744f6e18-a57a-11e9-a656-4889e7820c76' xmlns='urn:xmpp:reactions:0'> |
6a51749af7f4
util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11453
diff
changeset
|
88 <reaction>👋</reaction> |
6a51749af7f4
util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11453
diff
changeset
|
89 <reaction>🐢</reaction> |
6a51749af7f4
util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11453
diff
changeset
|
90 </reactions> |
11437
87a684df4b65
util.datamapper: Invent extension for using tag name as value
Kim Alvefur <zash@zash.se>
parents:
11436
diff
changeset
|
91 </message> |
87a684df4b65
util.datamapper: Invent extension for using tag name as value
Kim Alvefur <zash@zash.se>
parents:
11436
diff
changeset
|
92 ]]; |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
93 |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
94 d = { |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
95 to = "a@test"; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
96 from = "b@test"; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
97 type = "chat"; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
98 id = "1"; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
99 lang = "en"; |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
100 body = "Hello"; |
11494
284c822d4c3d
util.datamapper: Fix spelling in tests
Kim Alvefur <zash@zash.se>
parents:
11488
diff
changeset
|
101 delay = {from = "test"; stamp = "2021-03-07T15:59:08+00:00"; reason = "Because"}; |
11437
87a684df4b65
util.datamapper: Invent extension for using tag name as value
Kim Alvefur <zash@zash.se>
parents:
11436
diff
changeset
|
102 state = "active"; |
11438
b7807583de34
util.datamapper: Add logic for "boolean" tags here the presence means true
Kim Alvefur <zash@zash.se>
parents:
11437
diff
changeset
|
103 fallback = true; |
11439
9abcdfdcdb01
util.datamapper: Add support for mapping of elements where only one attribute matters
Kim Alvefur <zash@zash.se>
parents:
11438
diff
changeset
|
104 origin_id = "qgkmMdPB"; |
11480
0aa2971380e9
util.datamapper: Add test coverage of unwrapped arrays of objects
Kim Alvefur <zash@zash.se>
parents:
11476
diff
changeset
|
105 stanza_ids = {{id = "abc1"; by = "muc"}; {id = "xyz2"; by = "host"}}; |
11462
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
106 react = { |
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
107 to = "744f6e18-a57a-11e9-a656-4889e7820c76"; |
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
108 reactions = { |
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
109 "👋", |
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
110 "🐢", |
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
111 }; |
11457
6a51749af7f4
util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11453
diff
changeset
|
112 }; |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
113 }; |
11466
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
114 |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
115 disco_schema = { |
12133
11060c8919b6
util.datamapper: Add support for $ref pointers
Kim Alvefur <zash@zash.se>
parents:
11494
diff
changeset
|
116 ["$defs"] = { attr = { type = "string"; xml = { attribute = true } } }; |
11466
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
117 type = "object"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
118 xml = { |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
119 name = "iq"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
120 namespace = "jabber:client" |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
121 }; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
122 properties = { |
12818
74ed772ff5fb
util.datamapper: Simplify test schema
Kim Alvefur <zash@zash.se>
parents:
12580
diff
changeset
|
123 to = attr; |
74ed772ff5fb
util.datamapper: Simplify test schema
Kim Alvefur <zash@zash.se>
parents:
12580
diff
changeset
|
124 from = attr; |
74ed772ff5fb
util.datamapper: Simplify test schema
Kim Alvefur <zash@zash.se>
parents:
12580
diff
changeset
|
125 type = attr; |
74ed772ff5fb
util.datamapper: Simplify test schema
Kim Alvefur <zash@zash.se>
parents:
12580
diff
changeset
|
126 id = attr; |
11466
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
127 disco = { |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
128 type = "object"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
129 xml = { |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
130 name = "query"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
131 namespace = "http://jabber.org/protocol/disco#info" |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
132 }; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
133 properties = { |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
134 features = { |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
135 type = "array"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
136 items = { |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
137 type = "string"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
138 xml = { |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
139 name = "feature"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
140 x_single_attribute = "var"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
141 }; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
142 }; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
143 }; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
144 }; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
145 }; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
146 }; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
147 }; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
148 |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
149 disco_info = xml.parse[[ |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
150 <iq type="result" id="disco1" from="example.com"> |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
151 <query xmlns="http://jabber.org/protocol/disco#info"> |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
152 <feature var="urn:example:feature:1">wrong</feature> |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
153 <feature var="urn:example:feature:2"/> |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
154 <feature var="urn:example:feature:3"/> |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
155 <unrelated var="urn:example:feature:not"/> |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
156 </query> |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
157 </iq> |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
158 ]]; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
159 |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
160 disco = { |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
161 type="result"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
162 id="disco1"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
163 from="example.com"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
164 disco = { |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
165 features = { |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
166 "urn:example:feature:1"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
167 "urn:example:feature:2"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
168 "urn:example:feature:3"; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
169 }; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
170 }; |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
171 }; |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
172 end); |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
173 |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
174 describe("parse", function() |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
175 it("works", function() |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
176 assert.same(d, map.parse(s, x)); |
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
177 end); |
11466
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
178 |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
179 it("handles arrays", function () |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
180 assert.same(disco, map.parse(disco_schema, disco_info)); |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
181 end); |
c098d07e6717
util.datamapper: Finally implement support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11462
diff
changeset
|
182 |
11476
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
183 it("deals with locally built stanzas", function() |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
184 -- FIXME this could also be argued to be a util.stanza problem |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
185 local ver_schema = { |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
186 type = "object"; |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
187 xml = {name = "iq"}; |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
188 properties = { |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
189 type = {type = "string"; xml = {attribute = true}}; |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
190 id = {type = "string"; xml = {attribute = true}}; |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
191 version = { |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
192 type = "object"; |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
193 xml = {name = "query"; namespace = "jabber:iq:version"}; |
12580
a9dbf657c894
util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents:
12134
diff
changeset
|
194 -- properties should be assumed to be strings |
a9dbf657c894
util.datamapper: Improve handling of schemas with non-obvious "type"
Kim Alvefur <zash@zash.se>
parents:
12134
diff
changeset
|
195 properties = {name = true; version = {}; os = {}}; |
11476
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
196 }; |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
197 }; |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
198 }; |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
199 local ver_st = st.iq({type = "result"; id = "v1"}) |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
200 :query("jabber:iq:version") |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
201 :text_tag("name", "Prosody") |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
202 :text_tag("version", "trunk") |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
203 :text_tag("os", "Lua 5.3") |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
204 :reset(); |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
205 |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
206 local data = {type = "result"; id = "v1"; version = {name = "Prosody"; version = "trunk"; os = "Lua 5.3"}} |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
207 assert.same(data, map.parse(ver_schema, ver_st)); |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
208 end); |
83e127eb91f9
util.datamapper: Deal with locally built stanzas missing xmlns
Kim Alvefur <zash@zash.se>
parents:
11468
diff
changeset
|
209 |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
210 end); |
11436
5df9ffc25bb4
util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents:
11435
diff
changeset
|
211 |
5df9ffc25bb4
util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents:
11435
diff
changeset
|
212 describe("unparse", function() |
5df9ffc25bb4
util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents:
11435
diff
changeset
|
213 it("works", function() |
5df9ffc25bb4
util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents:
11435
diff
changeset
|
214 local u = map.unparse(s, d); |
5df9ffc25bb4
util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents:
11435
diff
changeset
|
215 assert.equal("message", u.name); |
5df9ffc25bb4
util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents:
11435
diff
changeset
|
216 assert.same(x.attr, u.attr); |
5df9ffc25bb4
util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents:
11435
diff
changeset
|
217 assert.equal(x:get_child_text("body"), u:get_child_text("body")); |
5df9ffc25bb4
util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents:
11435
diff
changeset
|
218 assert.equal(x:get_child_text("delay", "urn:xmpp:delay"), u:get_child_text("delay", "urn:xmpp:delay")); |
5df9ffc25bb4
util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents:
11435
diff
changeset
|
219 assert.same(x:get_child("delay", "urn:xmpp:delay").attr, u:get_child("delay", "urn:xmpp:delay").attr); |
11439
9abcdfdcdb01
util.datamapper: Add support for mapping of elements where only one attribute matters
Kim Alvefur <zash@zash.se>
parents:
11438
diff
changeset
|
220 assert.same(x:get_child("origin-id", "urn:xmpp:sid:0").attr, u:get_child("origin-id", "urn:xmpp:sid:0").attr); |
11462
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
221 assert.same(x:get_child("reactions", "urn:xmpp:reactions:0").attr, u:get_child("reactions", "urn:xmpp:reactions:0").attr); |
d1982b7eb00d
util.datamapper: Fix arrays nesting one level too deep
Kim Alvefur <zash@zash.se>
parents:
11458
diff
changeset
|
222 assert.same(2, #u:get_child("reactions", "urn:xmpp:reactions:0").tags); |
11457
6a51749af7f4
util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11453
diff
changeset
|
223 for _, tag in ipairs(x.tags) do |
11458
0e00fa518688
util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents:
11457
diff
changeset
|
224 if tag.name ~= "UNRELATED" then |
11457
6a51749af7f4
util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11453
diff
changeset
|
225 assert.truthy(u:get_child(tag.name, tag.attr.xmlns) or u:get_child(tag.name), tag:top_tag()) |
6a51749af7f4
util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11453
diff
changeset
|
226 end |
6a51749af7f4
util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11453
diff
changeset
|
227 end |
11458
0e00fa518688
util.datamapper: Limited support for unparsing simple arrays of strings
Kim Alvefur <zash@zash.se>
parents:
11457
diff
changeset
|
228 assert.equal(#x.tags-1, #u.tags) |
11457
6a51749af7f4
util.datamapper: Add initial support for parsing arrays
Kim Alvefur <zash@zash.se>
parents:
11453
diff
changeset
|
229 |
11436
5df9ffc25bb4
util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents:
11435
diff
changeset
|
230 end); |
11468
348b191cd850
util.datamapper: Complete array building support
Kim Alvefur <zash@zash.se>
parents:
11466
diff
changeset
|
231 |
348b191cd850
util.datamapper: Complete array building support
Kim Alvefur <zash@zash.se>
parents:
11466
diff
changeset
|
232 it("handles arrays", function () |
348b191cd850
util.datamapper: Complete array building support
Kim Alvefur <zash@zash.se>
parents:
11466
diff
changeset
|
233 local u = map.unparse(disco_schema, disco); |
348b191cd850
util.datamapper: Complete array building support
Kim Alvefur <zash@zash.se>
parents:
11466
diff
changeset
|
234 assert.equal("urn:example:feature:1", u:find("{http://jabber.org/protocol/disco#info}query/feature/@var")) |
348b191cd850
util.datamapper: Complete array building support
Kim Alvefur <zash@zash.se>
parents:
11466
diff
changeset
|
235 local n = 0; |
348b191cd850
util.datamapper: Complete array building support
Kim Alvefur <zash@zash.se>
parents:
11466
diff
changeset
|
236 for child in u:get_child("query", "http://jabber.org/protocol/disco#info"):childtags("feature") do |
348b191cd850
util.datamapper: Complete array building support
Kim Alvefur <zash@zash.se>
parents:
11466
diff
changeset
|
237 n = n + 1; |
348b191cd850
util.datamapper: Complete array building support
Kim Alvefur <zash@zash.se>
parents:
11466
diff
changeset
|
238 assert.equal(string.format("urn:example:feature:%d", n), child.attr.var); |
348b191cd850
util.datamapper: Complete array building support
Kim Alvefur <zash@zash.se>
parents:
11466
diff
changeset
|
239 end |
348b191cd850
util.datamapper: Complete array building support
Kim Alvefur <zash@zash.se>
parents:
11466
diff
changeset
|
240 end); |
348b191cd850
util.datamapper: Complete array building support
Kim Alvefur <zash@zash.se>
parents:
11466
diff
changeset
|
241 |
11436
5df9ffc25bb4
util.datamapper: Add 'unparse' for turning tables into XML
Kim Alvefur <zash@zash.se>
parents:
11435
diff
changeset
|
242 end); |
11435
a1fa6202fa13
util.datamapper: Library for extracting data from stanzas
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
243 end) |