-- RESTful API
--
-- Copyright (c) 2019 Kim Alvefur
--
-- This file is MIT/X11 licensed.
local errors = require "util.error";
local id = require "util.id";
local jid = require "util.jid";
local xml = require "util.xml";
local allow_any_source = module:get_host_type() == "component";
local validate_from_addresses = module:get_option_boolean("validate_from_addresses", true);
local function handle_post(event)
local request, response = event.request, event.response;
if request.headers.content_type ~= "application/xmpp+xml" then
return errors.new({ code = 415, text = "'application/xmpp+xml' expected" });
end
local payload, err = xml.parse(request.body);
if not payload then
-- parse fail
return errors.new({ code = 400, text = err });
end
local to = jid.prep(payload.attr.to);
if not to then
return errors.new({ code = 400, text = "Invalid destination JID" });
end
local from = module.host;
if allow_any_source and payload.attr.from then
from = jid.prep(payload.attr.from);
if not from then
return errors.new({ code = 400, text = "Invalid source JID" });
end
if validate_from_addresses and not jid.compare(from, module.host) then
return errors.new({ code = 403, text = "Source JID must belong to current host" });
end
end
payload.attr = {
from = from,
to = to,
id = payload.attr.id or id.medium(),
type = payload.attr.type,
["xml:lang"] = payload.attr["xml:lang"],
};
if payload.name == "iq" then
if payload.attr.type ~= "get" and payload.attr.type ~= "set" then
return errors.new({ code = 400, text = "'iq' stanza must be of type 'get' or 'set'" });
end
return module:send_iq(payload):next(
function (result)
response.headers.content_type = "application/xmpp+xml";
return tostring(result.stanza);
end,
function (error)
if error.context.stanza then
response.headers.content_type = "application/xmpp+xml";
return tostring(error.context.stanza);
else
return error;
end
end);
elseif payload.name == "message" or payload.name == "presence" then
if module:send(payload) then
return 202;
else
return 500;
end
else
return errors.new({ code = 400, text = "Invalid stanza, must be 'message', 'presence' or 'iq'." });
end
end
-- Handle stanzas submitted via HTTP
module:depends("http");
module:provides("http", {
route = {
POST = handle_post;
};
});