Software /
code /
prosody-modules
Comparison
mod_rest/mod_rest.lua @ 3794:4b258329e6e4
mod_rest: Initial commit of another RESTful API module
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 30 Dec 2019 04:04:34 +0100 |
child | 3795:f51308fcba83 |
comparison
equal
deleted
inserted
replaced
3793:0d3926e49b55 | 3794:4b258329e6e4 |
---|---|
1 -- RESTful API | |
2 -- | |
3 -- Copyright (c) 2019 Kim Alvefur | |
4 -- | |
5 -- This file is MIT/X11 licensed. | |
6 | |
7 local errors = require "util.error"; | |
8 local id = require "util.id"; | |
9 local jid = require "util.jid"; | |
10 local xml = require "util.xml"; | |
11 | |
12 local allow_any_source = module:get_host_type() == "component"; | |
13 local validate_from_addresses = module:get_option_boolean("validate_from_addresses", true); | |
14 | |
15 local function handle_post(event) | |
16 local request, response = event.request, event.response; | |
17 if request.headers.content_type ~= "application/xmpp+xml" then | |
18 return errors.new({ code = 415, text = "'application/xmpp+xml' expected" }); | |
19 end | |
20 local payload, err = xml.parse(request.body); | |
21 if not payload then | |
22 -- parse fail | |
23 return errors.new({ code = 400, text = err }); | |
24 end | |
25 local to = jid.prep(payload.attr.to); | |
26 if not to then | |
27 return errors.new({ code = 400, text = "Invalid destination JID" }); | |
28 end | |
29 local from = module.host; | |
30 if allow_any_source and payload.attr.from then | |
31 from = jid.prep(payload.attr.from); | |
32 if not from then | |
33 return errors.new({ code = 400, text = "Invalid source JID" }); | |
34 end | |
35 if validate_from_addresses and not jid.compare(from, module.host) then | |
36 return errors.new({ code = 403, text = "Source JID must belong to current host" }); | |
37 end | |
38 end | |
39 payload.attr = { | |
40 from = from, | |
41 to = to, | |
42 id = payload.attr.id or id.medium(), | |
43 type = payload.attr.type, | |
44 ["xml:lang"] = payload.attr["xml:lang"], | |
45 }; | |
46 if payload.name == "iq" then | |
47 if payload.attr.type ~= "get" and payload.attr.type ~= "set" then | |
48 return errors.new({ code = 400, text = "'iq' stanza must be of type 'get' or 'set'" }); | |
49 end | |
50 return module:send_iq(payload):next( | |
51 function (result) | |
52 response.headers.content_type = "application/xmpp+xml"; | |
53 return tostring(result.stanza); | |
54 end, | |
55 function (error) | |
56 if error.context.stanza then | |
57 response.headers.content_type = "application/xmpp+xml"; | |
58 return tostring(error.context.stanza); | |
59 else | |
60 return error; | |
61 end | |
62 end); | |
63 elseif payload.name == "message" or payload.name == "presence" then | |
64 if module:send(payload) then | |
65 return 202; | |
66 else | |
67 return 500; | |
68 end | |
69 else | |
70 return errors.new({ code = 400, text = "Invalid stanza, must be 'message', 'presence' or 'iq'." }); | |
71 end | |
72 end | |
73 | |
74 -- Handle stanzas submitted via HTTP | |
75 module:depends("http"); | |
76 module:provides("http", { | |
77 route = { | |
78 POST = handle_post; | |
79 }; | |
80 }); |