diff options
-rw-r--r-- | xml.lua | 73 | ||||
-rw-r--r-- | xmpp.lua | 87 |
2 files changed, 160 insertions, 0 deletions
@@ -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 + |