module:depends("http");
local http = require "net.http";
local format = require "util.format".format;
local json_encode = require "util.json".encode;
local promise = require "util.promise";
local xml = require "util.xml";
local t_insert = table.insert;
local function new_options(host)
return {
headers = {
["Content-Type"] = "text/xml; charset=utf-8",
["Host"] = host,
},
method = "POST",
};
end
local function connect_to_bosh(url, hostname)
local rid = math.random(100000, 100000000)
local options = new_options(hostname);
options.body = format([[
]], data.sid, data.rid);
data.rid = data.rid + 1;
return promise.new(function (on_fulfilled, on_error)
if data.mechanisms["ANONYMOUS"] == nil then
on_error("No SASL ANONYMOUS mechanism supported on this host.");
return;
end
assert(http.request(data.url, options, function (body, code)
if code ~= 200 then
on_error("Failed to fetch, HTTP error code "..code);
return;
end
local body = xml.parse(body);
local success = body:get_child("success", "urn:ietf:params:xml:ns:xmpp-sasl");
if success then
data.mechanisms = nil;
on_fulfilled(data);
else
on_error("Authentication failed.");
end
end));
end);
end;
local function restart_stream(data)
local options = new_options();
options.body = format([[
]], data.sid, data.rid);
data.rid = data.rid + 1;
return promise.new(function (on_fulfilled, on_error)
assert(http.request(data.url, options, function (body, code)
if code ~= 200 then
on_error("Failed to fetch, HTTP error code "..code);
return;
end
local body = xml.parse(body);
local jid = body:get_child("iq", "jabber:client")
:get_child("bind", "urn:ietf:params:xml:ns:xmpp-bind")
:get_child_text("jid", "urn:ietf:params:xml:ns:xmpp-bind");
on_fulfilled(json_encode({rid = data.rid, sid = data.sid, jid = jid}));
end));
end);
end;
module:provides("http", {
route = {
["GET"] = function (event)
return connect_to_bosh("http://[::1]:5280/http-bind", module.host)
:next(authenticate)
:next(restart_stream)
:next(bind);
end;
};
});