author | Kim Alvefur <zash@zash.se> |
Sat, 25 Jan 2020 01:55:23 +0100 | |
changeset 3862 | 29c39876c4af |
parent 3847 | c065b7670c89 |
child 3865 | ede3d1724dd1 |
permissions | -rw-r--r-- |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
1 |
-- RESTful API |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
2 |
-- |
3807
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3806
diff
changeset
|
3 |
-- Copyright (c) 2019-2020 Kim Alvefur |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
4 |
-- |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
5 |
-- This file is MIT/X11 licensed. |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
6 |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
7 |
local errors = require "util.error"; |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
8 |
local http = require "net.http"; |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
9 |
local id = require "util.id"; |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
10 |
local jid = require "util.jid"; |
3817 | 11 |
local json = require "util.json"; |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
12 |
local st = require "util.stanza"; |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
13 |
local xml = require "util.xml"; |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
14 |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
15 |
local allow_any_source = module:get_host_type() == "component"; |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
16 |
local validate_from_addresses = module:get_option_boolean("validate_from_addresses", true); |
3806
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
17 |
local secret = assert(module:get_option_string("rest_credentials"), "rest_credentials is a required setting"); |
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
18 |
local auth_type = assert(secret:match("^%S+"), "Format of rest_credentials MUST be like 'Bearer secret'"); |
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
19 |
assert(auth_type == "Bearer", "Only 'Bearer' is supported in rest_credentials"); |
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
20 |
|
3817 | 21 |
local jsonmap = module:require"jsonmap"; |
3806
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
22 |
-- Bearer token |
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
23 |
local function check_credentials(request) |
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
24 |
return request.headers.authorization == secret; |
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
25 |
end |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
26 |
|
3814
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
27 |
local function parse(mimetype, data) |
3829
802087d3155a
mod_rest: Fix traceback on missing content-type header
Kim Alvefur <zash@zash.se>
parents:
3828
diff
changeset
|
28 |
mimetype = mimetype and mimetype:match("^[^; ]*"); |
3814
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
29 |
if mimetype == "application/xmpp+xml" then |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
30 |
return xml.parse(data); |
3817 | 31 |
elseif mimetype == "application/json" then |
32 |
local parsed, err = json.decode(data); |
|
33 |
if not parsed then |
|
34 |
return parsed, err; |
|
35 |
end |
|
36 |
return jsonmap.json2st(parsed); |
|
3814
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
37 |
elseif mimetype == "text/plain" then |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
38 |
return st.message({ type = "chat" }, data); |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
39 |
end |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
40 |
return nil, "unknown-payload-type"; |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
41 |
end |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
42 |
|
3817 | 43 |
local supported_types = { "application/xmpp+xml", "application/json" }; |
44 |
||
45 |
local function decide_type(accept) |
|
46 |
-- assumes the accept header is sorted |
|
47 |
local ret = supported_types[1]; |
|
48 |
for i = 2, #supported_types do |
|
49 |
if (accept:find(supported_types[i], 1, true) or 1000) < (accept:find(ret, 1, true) or 1000) then |
|
50 |
ret = supported_types[i]; |
|
51 |
end |
|
52 |
end |
|
53 |
return ret; |
|
3815
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3814
diff
changeset
|
54 |
end |
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3814
diff
changeset
|
55 |
|
3816
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3815
diff
changeset
|
56 |
local function encode(type, s) |
3817 | 57 |
if type == "application/json" then |
58 |
return json.encode(jsonmap.st2json(s)); |
|
59 |
elseif type == "text/plain" then |
|
60 |
return s:get_child_text("body") or ""; |
|
61 |
end |
|
3816
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3815
diff
changeset
|
62 |
return tostring(s); |
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3815
diff
changeset
|
63 |
end |
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3815
diff
changeset
|
64 |
|
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
65 |
local function handle_post(event) |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
66 |
local request, response = event.request, event.response; |
3806
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
67 |
if not request.headers.authorization then |
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
68 |
response.headers.www_authenticate = ("%s realm=%q"):format(auth_type, module.host.."/"..module.name); |
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
69 |
return 401; |
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
70 |
elseif not check_credentials(request) then |
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
71 |
return 401; |
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3805
diff
changeset
|
72 |
end |
3814
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
73 |
local payload, err = parse(request.headers.content_type, request.body); |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
74 |
if not payload then |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
75 |
-- parse fail |
3847
c065b7670c89
mod_rest: Return a friendly message for parse errors
Kim Alvefur <zash@zash.se>
parents:
3846
diff
changeset
|
76 |
return errors.new({ code = 400, text = "Failed to parse payload" }, { error = err, type = request.headers.content_type, data = request.body }); |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
77 |
end |
3805
d59fb4dcf100
mod_rest: Verify that @xmlns is left empty
Kim Alvefur <zash@zash.se>
parents:
3803
diff
changeset
|
78 |
if payload.attr.xmlns then |
3808
d74509cd35fb
mod_rest: Use HTTP status 422 for stanza problems
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
79 |
return errors.new({ code = 422, text = "'xmlns' attribute must be empty" }); |
3809
683b06c0348f
mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents:
3808
diff
changeset
|
80 |
elseif payload.name ~= "message" and payload.name ~= "presence" and payload.name ~= "iq" then |
683b06c0348f
mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents:
3808
diff
changeset
|
81 |
return errors.new({ code = 422, text = "Invalid stanza, must be 'message', 'presence' or 'iq'." }); |
3805
d59fb4dcf100
mod_rest: Verify that @xmlns is left empty
Kim Alvefur <zash@zash.se>
parents:
3803
diff
changeset
|
82 |
end |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
83 |
local to = jid.prep(payload.attr.to); |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
84 |
if not to then |
3808
d74509cd35fb
mod_rest: Use HTTP status 422 for stanza problems
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
85 |
return errors.new({ code = 422, text = "Invalid destination JID" }); |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
86 |
end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
87 |
local from = module.host; |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
88 |
if allow_any_source and payload.attr.from then |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
89 |
from = jid.prep(payload.attr.from); |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
90 |
if not from then |
3808
d74509cd35fb
mod_rest: Use HTTP status 422 for stanza problems
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
91 |
return errors.new({ code = 422, text = "Invalid source JID" }); |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
92 |
end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
93 |
if validate_from_addresses and not jid.compare(from, module.host) then |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
94 |
return errors.new({ code = 403, text = "Source JID must belong to current host" }); |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
95 |
end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
96 |
end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
97 |
payload.attr = { |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
98 |
from = from, |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
99 |
to = to, |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
100 |
id = payload.attr.id or id.medium(), |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
101 |
type = payload.attr.type, |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
102 |
["xml:lang"] = payload.attr["xml:lang"], |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
103 |
}; |
3807
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3806
diff
changeset
|
104 |
module:log("debug", "Received[rest]: %s", payload:top_tag()); |
3820
8473fd2d09c1
mod_rest: Default to replying with same type as request
Kim Alvefur <zash@zash.se>
parents:
3819
diff
changeset
|
105 |
local send_type = decide_type((request.headers.accept or "") ..",".. request.headers.content_type) |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
106 |
if payload.name == "iq" then |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
107 |
if payload.attr.type ~= "get" and payload.attr.type ~= "set" then |
3808
d74509cd35fb
mod_rest: Use HTTP status 422 for stanza problems
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
108 |
return errors.new({ code = 422, text = "'iq' stanza must be of type 'get' or 'set'" }); |
3836
0d4146cf9fbc
mod_rest: Enforce single child policy for outgoing it stanzas
Kim Alvefur <zash@zash.se>
parents:
3829
diff
changeset
|
109 |
elseif #payload.tags ~= 1 then |
0d4146cf9fbc
mod_rest: Enforce single child policy for outgoing it stanzas
Kim Alvefur <zash@zash.se>
parents:
3829
diff
changeset
|
110 |
return errors.new({ code = 422, text = "'iq' stanza must have exactly one child tag" }); |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
111 |
end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
112 |
return module:send_iq(payload):next( |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
113 |
function (result) |
3807
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3806
diff
changeset
|
114 |
module:log("debug", "Sending[rest]: %s", result.stanza:top_tag()); |
3815
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3814
diff
changeset
|
115 |
response.headers.content_type = send_type; |
3816
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3815
diff
changeset
|
116 |
return encode(send_type, result.stanza); |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
117 |
end, |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
118 |
function (error) |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
119 |
if error.context.stanza then |
3815
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3814
diff
changeset
|
120 |
response.headers.content_type = send_type; |
3807
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3806
diff
changeset
|
121 |
module:log("debug", "Sending[rest]: %s", error.context.stanza:top_tag()); |
3816
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3815
diff
changeset
|
122 |
return encode(send_type, error.context.stanza); |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
123 |
else |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
124 |
return error; |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
125 |
end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
126 |
end); |
3809
683b06c0348f
mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents:
3808
diff
changeset
|
127 |
else |
3800
d1ad10b76b00
mod_rest: Catch one (1) reply to a POST-ed stanza from an internal source
Kim Alvefur <zash@zash.se>
parents:
3799
diff
changeset
|
128 |
local origin = {}; |
d1ad10b76b00
mod_rest: Catch one (1) reply to a POST-ed stanza from an internal source
Kim Alvefur <zash@zash.se>
parents:
3799
diff
changeset
|
129 |
function origin.send(stanza) |
3807
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3806
diff
changeset
|
130 |
module:log("debug", "Sending[rest]: %s", stanza:top_tag()); |
3815
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3814
diff
changeset
|
131 |
response.headers.content_type = send_type; |
3816
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3815
diff
changeset
|
132 |
response:send(encode(send_type, stanza)); |
3800
d1ad10b76b00
mod_rest: Catch one (1) reply to a POST-ed stanza from an internal source
Kim Alvefur <zash@zash.se>
parents:
3799
diff
changeset
|
133 |
return true; |
d1ad10b76b00
mod_rest: Catch one (1) reply to a POST-ed stanza from an internal source
Kim Alvefur <zash@zash.se>
parents:
3799
diff
changeset
|
134 |
end |
3818
0dede5b0ab27
mod_rest: Fix return status when sending and forgetting
Kim Alvefur <zash@zash.se>
parents:
3817
diff
changeset
|
135 |
module:send(payload, origin); |
0dede5b0ab27
mod_rest: Fix return status when sending and forgetting
Kim Alvefur <zash@zash.se>
parents:
3817
diff
changeset
|
136 |
return 202; |
3798
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
137 |
end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
138 |
end |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
139 |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
140 |
-- Handle stanzas submitted via HTTP |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
141 |
module:depends("http"); |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
142 |
module:provides("http", { |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
143 |
route = { |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
144 |
POST = handle_post; |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
145 |
}; |
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
146 |
}); |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
147 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
148 |
-- Forward stanzas from XMPP to HTTP and return any reply |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
149 |
local rest_url = module:get_option_string("rest_callback_url", nil); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
150 |
if rest_url then |
3815
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3814
diff
changeset
|
151 |
local send_type = module:get_option_string("rest_callback_content_type", "application/xmpp+xml"); |
3817 | 152 |
if send_type == "json" then |
153 |
send_type = "application/json"; |
|
154 |
end |
|
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
155 |
|
3801
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
156 |
local code2err = { |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
157 |
[400] = { condition = "bad-request"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
158 |
[401] = { condition = "not-authorized"; type = "auth" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
159 |
[402] = { condition = "not-authorized"; type = "auth" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
160 |
[403] = { condition = "forbidden"; type = "auth" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
161 |
[404] = { condition = "item-not-found"; type = "cancel" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
162 |
[406] = { condition = "not-acceptable"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
163 |
[408] = { condition = "remote-server-timeout"; type = "wait" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
164 |
[409] = { condition = "conflict"; type = "cancel" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
165 |
[410] = { condition = "gone"; type = "cancel" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
166 |
[411] = { condition = "bad-request"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
167 |
[412] = { condition = "bad-request"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
168 |
[413] = { condition = "resource-constraint"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
169 |
[414] = { condition = "resource-constraint"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
170 |
[415] = { condition = "bad-request"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
171 |
[429] = { condition = "resource-constraint"; type = "wait" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
172 |
[431] = { condition = "resource-constraint"; type = "wait" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
173 |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
174 |
[500] = { condition = "internal-server-error"; type = "cancel" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
175 |
[501] = { condition = "feature-not-implemented"; type = "modify" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
176 |
[502] = { condition = "remote-server-timeout"; type = "wait" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
177 |
[503] = { condition = "service-unavailable"; type = "cancel" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
178 |
[504] = { condition = "remote-server-timeout"; type = "wait" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
179 |
[507] = { condition = "resource-constraint"; type = "wait" }; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
180 |
}; |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
181 |
|
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
182 |
local function handle_stanza(event) |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
183 |
local stanza, origin = event.stanza, event.origin; |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
184 |
local reply_needed = stanza.name == "iq"; |
3802
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
185 |
local receipt; |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
186 |
|
3828
a0b8ec44a36b
mod_rest: Stanzas of type error don't need a reply
Kim Alvefur <zash@zash.se>
parents:
3825
diff
changeset
|
187 |
if stanza.attr.type == "error" then |
a0b8ec44a36b
mod_rest: Stanzas of type error don't need a reply
Kim Alvefur <zash@zash.se>
parents:
3825
diff
changeset
|
188 |
reply_needed = false; |
a0b8ec44a36b
mod_rest: Stanzas of type error don't need a reply
Kim Alvefur <zash@zash.se>
parents:
3825
diff
changeset
|
189 |
end |
a0b8ec44a36b
mod_rest: Stanzas of type error don't need a reply
Kim Alvefur <zash@zash.se>
parents:
3825
diff
changeset
|
190 |
|
3802
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
191 |
if stanza.name == "message" and stanza.attr.id and stanza:get_child("urn:xmpp:receipts", "request") then |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
192 |
reply_needed = true; |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
193 |
receipt = st.stanza("received", { xmlns = "urn:xmpp:receipts", id = stanza.id }); |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
194 |
end |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
195 |
|
3816
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3815
diff
changeset
|
196 |
local request_body = encode(send_type, stanza); |
3803
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
197 |
|
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
198 |
-- Keep only the top level element and let the rest be GC'd |
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
199 |
stanza = st.clone(stanza, true); |
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
200 |
|
3807
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3806
diff
changeset
|
201 |
module:log("debug", "Sending[rest]: %s", stanza:top_tag()); |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
202 |
http.request(rest_url, { |
3803
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
203 |
body = request_body, |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
204 |
headers = { |
3815
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3814
diff
changeset
|
205 |
["Content-Type"] = send_type, |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
206 |
["Content-Language"] = stanza.attr["xml:lang"], |
3817 | 207 |
Accept = table.concat(supported_types, ", "); |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
208 |
}, |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
209 |
}, function (body, code, response) |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
210 |
if (code == 202 or code == 204) and not reply_needed then |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
211 |
-- Delivered, no reply |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
212 |
return; |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
213 |
end |
3814
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
214 |
local reply; |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
215 |
|
3814
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
216 |
local parsed, err = parse(response.headers["content-type"], body); |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
217 |
if not parsed then |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
218 |
module:log("warn", "Failed parsing data from REST callback: %s, %q", err, body); |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
219 |
elseif parsed.name ~= stanza.name then |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
220 |
module:log("warn", "REST callback responded with the wrong stanza type, got %s but expected %s", parsed.name, stanza.name); |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
221 |
else |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
222 |
parsed.attr = { |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
223 |
from = stanza.attr.to, |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
224 |
to = stanza.attr.from, |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
225 |
id = parsed.attr.id or id.medium(); |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
226 |
type = parsed.attr.type, |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
227 |
["xml:lang"] = parsed.attr["xml:lang"], |
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
228 |
}; |
3825
11272a3233ce
mod_rest: Fix replying to groupchat messages
Kim Alvefur <zash@zash.se>
parents:
3820
diff
changeset
|
229 |
if parsed.name == "message" and parsed.attr.type == "groupchat" then |
11272a3233ce
mod_rest: Fix replying to groupchat messages
Kim Alvefur <zash@zash.se>
parents:
3820
diff
changeset
|
230 |
parsed.attr.to = jid.bare(stanza.attr.from); |
11272a3233ce
mod_rest: Fix replying to groupchat messages
Kim Alvefur <zash@zash.se>
parents:
3820
diff
changeset
|
231 |
end |
3862
29c39876c4af
mod_rest: Ensure iq responses have type result if they're not errors
Kim Alvefur <zash@zash.se>
parents:
3847
diff
changeset
|
232 |
if not stanza.attr.type and parsed:get_child("error") then |
29c39876c4af
mod_rest: Ensure iq responses have type result if they're not errors
Kim Alvefur <zash@zash.se>
parents:
3847
diff
changeset
|
233 |
parsed.attr.type = "error"; |
29c39876c4af
mod_rest: Ensure iq responses have type result if they're not errors
Kim Alvefur <zash@zash.se>
parents:
3847
diff
changeset
|
234 |
end |
29c39876c4af
mod_rest: Ensure iq responses have type result if they're not errors
Kim Alvefur <zash@zash.se>
parents:
3847
diff
changeset
|
235 |
if parsed.attr.type == "error" then |
3814
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
236 |
parsed.attr.id = stanza.attr.id; |
3862
29c39876c4af
mod_rest: Ensure iq responses have type result if they're not errors
Kim Alvefur <zash@zash.se>
parents:
3847
diff
changeset
|
237 |
elseif parsed.name == "iq" then |
29c39876c4af
mod_rest: Ensure iq responses have type result if they're not errors
Kim Alvefur <zash@zash.se>
parents:
3847
diff
changeset
|
238 |
parsed.attr.id = stanza.attr.id; |
29c39876c4af
mod_rest: Ensure iq responses have type result if they're not errors
Kim Alvefur <zash@zash.se>
parents:
3847
diff
changeset
|
239 |
parsed.attr.type = "result"; |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
240 |
end |
3814
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
241 |
reply = parsed; |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
242 |
end |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
243 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
244 |
if not reply then |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
245 |
local code_hundreds = code - (code % 100); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
246 |
if code_hundreds == 200 then |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
247 |
reply = st.reply(stanza); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
248 |
if stanza.name ~= "iq" then |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
249 |
reply.attr.id = id.medium(); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
250 |
end |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
251 |
-- TODO presence/status=body ? |
3801
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
252 |
elseif code2err[code] then |
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3800
diff
changeset
|
253 |
reply = st.error_reply(stanza, errors.new(code, nil, code2err)); |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
254 |
elseif code_hundreds == 400 then |
3814
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
255 |
reply = st.error_reply(stanza, "modify", "bad-request", body); |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
256 |
elseif code_hundreds == 500 then |
3814
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
257 |
reply = st.error_reply(stanza, "cancel", "internal-server-error", body); |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
258 |
else |
3814
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
259 |
reply = st.error_reply(stanza, "cancel", "undefined-condition", body); |
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
260 |
end |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
261 |
end |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
262 |
|
3802
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
263 |
if receipt then |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
264 |
reply:add_direct_child(receipt); |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
265 |
end |
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
266 |
|
3807
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3806
diff
changeset
|
267 |
module:log("debug", "Received[rest]: %s", reply:top_tag()); |
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3806
diff
changeset
|
268 |
|
3799
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
269 |
origin.send(reply); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
270 |
end); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
271 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
272 |
return true; |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
273 |
end |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
274 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
275 |
if module:get_host_type() == "component" then |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
276 |
module:hook("iq/bare", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
277 |
module:hook("message/bare", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
278 |
module:hook("presence/bare", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
279 |
module:hook("iq/full", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
280 |
module:hook("message/full", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
281 |
module:hook("presence/full", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
282 |
module:hook("iq/host", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
283 |
module:hook("message/host", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
284 |
module:hook("presence/host", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
285 |
else |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
286 |
-- Don't override everything on normal VirtualHosts |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
287 |
module:hook("iq/host", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
288 |
module:hook("message/host", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
289 |
module:hook("presence/host", handle_stanza, -1); |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
290 |
end |
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
291 |
end |
3846
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
292 |
|
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
293 |
local http_server = require "net.http.server"; |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
294 |
module:hook_object_event(http_server, "http-error", function (event) |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
295 |
local request, response = event.request, event.response; |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
296 |
if true or decide_type(request and request.headers.accept or "") == "application/json" then |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
297 |
if response then |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
298 |
response.headers.content_type = "application/json"; |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
299 |
end |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
300 |
return json.encode({ |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
301 |
type = "error", |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
302 |
error = event.error, |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
303 |
code = event.code, |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
304 |
}); |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
305 |
end |
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3836
diff
changeset
|
306 |
end, 10); |