Mercurial > xmpp-account-manager
changeset 1:d6df73b466f6
Implement XEP-0156 to discover the right BOSH endpoint.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 21 Dec 2018 23:44:18 +0100 |
parents | 2a8d4e8600d0 |
children | db033e5eabcb |
files | avatar.js client.js index.xhtml nickname.js util.js |
diffstat | 5 files changed, 70 insertions(+), 44 deletions(-) [+] |
line wrap: on
line diff
--- a/avatar.js +++ b/avatar.js @@ -148,19 +148,6 @@ function initAvatar(connection) { sha1_reader.readAsArrayBuffer(file); }); - function nsResolver(prefix) { - return { - pubsub: 'http://jabber.org/protocol/pubsub', - avatar_metadata: 'urn:xmpp:avatar:metadata', - avatar_data: 'urn:xmpp:avatar:data', - }[prefix] || null; - } - - function parseXPath(elem, xpath) - { - return elem.getRootNode().evaluate(xpath, elem, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; - } - function friendlyDataSize(bytes) { let unit = 'B' if (bytes >= 1024) {
--- a/client.js +++ b/client.js @@ -1,21 +1,7 @@ 'use strict'; -const BOSH_SERVICE = 'https://bosh.linkmauve.fr/'; - -function rawInput(data) -{ - console.log('RECV', data); -} - -function rawOutput(data) -{ - console.log('SENT', data); -} - document.addEventListener('DOMContentLoaded', function () { - const connection = new Strophe.Connection(BOSH_SERVICE); - connection.rawInput = rawInput; - connection.rawOutput = rawOutput; + let connection = null; const jid_element = document.getElementById('jid'); const pass_element = document.getElementById('pass'); @@ -25,17 +11,62 @@ document.addEventListener('DOMContentLoa const avatar_img = document.getElementById('avatar'); + function rawInput(data) + { + console.log('RECV', data); + } + + function rawOutput(data) + { + console.log('SENT', data); + } + connect_button.addEventListener('click', function (evt) { if (connect_button.value == 'connect') { - connection.connect(jid_element.value, - pass_element.value, - onConnect); - } else { + const jid = jid_element.value; + getBOSHService(jid).then((bosh_service) => { + connection = new Strophe.Connection(bosh_service); + connection.rawInput = rawInput; + connection.rawOutput = rawOutput; + connection.connect(jid, + pass_element.value, + onConnect); + }); + } else if (connection != null) { connection.disconnect(); } evt.preventDefault(); }); + function getBOSHService(jid) + { + return new Promise((resolve, reject) => { + const [nodepart, domainpart] = jid.split('@', 2); + //const url = 'https://' + domainpart + '/.well-known/host-meta'; + const url = '/.well-known/host-meta'; + const xhr = new XMLHttpRequest(); + xhr.onload = function (evt) { + const xml = evt.target.responseXML; + const links = parseXPath(xml, './xrd:XRD/xrd:Link', XPathResult.ORDERED_NODE_ITERATOR_TYPE); + let bosh_service = null; + while (true) { + const link = links.iterateNext(); + if (!link) + break; + if (link.getAttributeNS(null, 'rel') == 'urn:xmpp:alt-connections:xbosh') { + bosh_service = link.getAttributeNS(null, 'href'); + break; + } + // TODO: also support WebSocket. + } + console.log('bosh_service', bosh_service); + resolve(bosh_service); + }; + xhr.open('GET', url); + xhr.send(); + }); + } + function onConnect(status) { if (status == Strophe.Status.CONNECTING) {
--- a/index.xhtml +++ b/index.xhtml @@ -89,6 +89,7 @@ </dl> </footer> +<script src="util.js"/> <script src="strophe.js"/> <script src="client.js"/> <script src="nickname.js"/>
--- a/nickname.js +++ b/nickname.js @@ -9,18 +9,6 @@ function initNickname(connection) { .c('items', {node: 'http://jabber.org/protocol/nick'}); connection.sendIQ(iq, onNickname, onNicknameRetrievalError.bind(null, 'PubSub query failed.')); - function nsResolver(prefix) { - return { - pubsub: 'http://jabber.org/protocol/pubsub', - nickname: 'http://jabber.org/protocol/nick', - }[prefix] || null; - } - - function parseXPath(elem, xpath) - { - return elem.getRootNode().evaluate(xpath, elem, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; - } - function onNickname(result_iq) { const item = parseXPath(result_iq, './pubsub:pubsub/pubsub:items/pubsub:item');
new file mode 100644 --- /dev/null +++ b/util.js @@ -0,0 +1,19 @@ +function nsResolver(prefix) { + return { + xrd: 'http://docs.oasis-open.org/ns/xri/xrd-1.0', + pubsub: 'http://jabber.org/protocol/pubsub', + avatar_metadata: 'urn:xmpp:avatar:metadata', + avatar_data: 'urn:xmpp:avatar:data', + nickname: 'http://jabber.org/protocol/nick', + }[prefix] || null; +} + +function parseXPath(elem, xpath, result) +{ + if (result === undefined) + result = XPathResult.FIRST_ORDERED_NODE_TYPE; + const value = elem.getRootNode().evaluate(xpath, elem, nsResolver, result, null); + if (result == XPathResult.FIRST_ORDERED_NODE_TYPE) + return value.singleNodeValue; + return value; +}