summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xml.lua73
-rw-r--r--xmpp.lua87
2 files changed, 160 insertions, 0 deletions
diff --git a/xml.lua b/xml.lua
new file mode 100644
index 0000000..7a0758a
--- /dev/null
+++ b/xml.lua
@@ -0,0 +1,73 @@
+local function parseargs(s)
+ local arg = {}
+ string.gsub(s, "([%-%w]+)=([\"'])(.-)%2", function (w, _, a)
+ arg[w] = a
+ end)
+ return arg
+end
+
+local psingle
+
+local function pmulti(s, i, parent)
+ ::again::
+ local nexti, child = psingle(s, i)
+ if child.close and child.label == parent.label then
+ return nexti, parent
+ else
+ table.insert(parent, child)
+ i = nexti
+ goto again
+ end
+end
+
+psingle = function(s, i)
+ i = i or 1
+ local ts,j,c,label,xarg,empty = s:find("<(%/?)([%w:]+)(.-)(%/?)>", i)
+ if not ts then
+ local rest = s:sub(i)
+ if rest:find("<",i) then
+ error('ill formed (eof?)')
+ elseif #rest == 0 then
+ error('empty string')
+ else
+ return i+#rest, rest
+ end
+ end
+ local nexti = j+1
+
+ local pretext = s:sub(i, ts-1)
+ if not pretext:find("^%s*$") then -- not entirely whitespace
+ return ts, pretext
+ end
+
+ if empty == "/" then
+ return nexti, {label=label, xarg=parseargs(xarg), empty=true}
+ elseif c == "" then -- start tag
+ return multi(s, nexti, {label=label, xarg=parseargs(xarg)})
+ else -- end tag
+ return nexti, {label=label, close=true}
+ end
+end
+
+local wrap
+do
+ local _, cqa = pcall(require, 'cqueues.auxlib')
+ wrap = cqa and cqa.wrap or coroutine.wrap
+end
+local function stanzae(getmore)
+ return wrap(function()
+ local buf = ''
+ while true do
+ local ok, ni, el = pcall(psingle, buf)
+ if ok then
+ coroutine.yield(el)
+ buf = buf:sub(ni)
+ else
+ buf = buf..getmore()
+ end
+ end
+ end)
+end
+
+
+return { psingle = psingle, stanzae = stanzae, wrap=wrap }
diff --git a/xmpp.lua b/xmpp.lua
new file mode 100644
index 0000000..a2ea6cb
--- /dev/null
+++ b/xmpp.lua
@@ -0,0 +1,87 @@
+local jid = 'wilson@ubq323.website'
+local server = 'ubq323.website'
+local auth = 'AHdpbHNvbgBncmVnb3J5PDM='
+local resource = 'cheese'
+
+
+local cqueues = require'cqueues'
+local socket = require'cqueues.socket'
+
+
+local function connect(...)
+ local sock = assert(socket.connect(... or server, 5222))
+ sock:setmode('bn','bn')
+
+ local start = ([[
+<?xml version='1.0'?><stream:stream from='%s' to='%s' version='1.0' xml:lang='en' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams'>]]):format(jid, server)
+
+ local function check_and_send(test, text)
+ local x = sock:read('-2048')
+ print(x)
+ assert(x:find(test))
+ if text then sock:write(text) end
+ end
+
+ sock:write(start)
+ check_and_send('starttls', [[<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>]])
+ check_and_send('proceed', nil)
+ sock:starttls()
+ sock:write(start)
+ check_and_send('PLAIN',
+ ([[<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>%s</auth>]]):format(auth))
+ check_and_send('success',start)
+ check_and_send('bind', ([[<iq type='set' id='aaa'>
+ <bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>%s</resource></bind></iq>
+ ]]):format(resource))
+ check_and_send('jid','<presence/>')
+
+ return sock
+end
+
+-- sock:write[[
+-- <iq type='set' id='1234'>
+-- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+-- <publish node='urn:xmpp:avatar:metadata'>
+-- <item id='89229147c33129fd8d1ab177b6cbea725e72a8b4'>
+-- <metadata xmlns='urn:xmpp:avatar:metadata'>
+-- <info bytes='54660'
+-- height='213'
+-- width='203'
+-- id='89229147c33129fd8d1ab177b6cbea725e72a8b4'
+-- type='image/png'
+-- url='https://ubq323.website/files/itAE9dXL.png'/>
+-- </metadata>
+-- </item>
+-- </publish>
+-- </pubsub>
+-- </iq>]]
+
+local sock = connect(...)
+
+local mucs = {
+ 'ja@conference.ubq323.website'
+}
+
+for _, muc in ipairs(mucs) do
+ sock:write(([[
+ <presence to='%s'>
+ <x xmlns='http://jabber.org/protocol/muc'/>
+ </presence>]]):format(muc .. '/wilson'))
+end
+
+
+-- sock:write[[<iq type='get'
+-- to='ja@conference.ubq323.website/viba'
+-- id='retrieve1'>
+-- <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+-- <items node='urn:xmpp:avatar:data'>
+-- <item id='9c78e85250ef6f74f44f3142f559cc4f4465298c'/>
+-- </items>
+-- </pubsub>
+-- </iq>]]
+
+local xml=require'xml'
+for x in xml.stanzae(function() return sock:read('-2048') end) do
+ print(x)
+end
+