Mercurial > prosody-modules
annotate mod_rest/mod_rest.lua @ 3965:2b10e51d85a6
mod_muc_limits: Add config option to limit to join stanzas only
This is a bit more limited in pre-0.11 MUC modules, because it just
detects stanzas sent to full JIDs (which would include all presence
and nick changes).
This option is useful for setups where users are typically unaffiliated,
but trusted (e.g. if access to the room is gated through some other
means such as password/token auth).
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Fri, 03 Apr 2020 12:26:56 +0100 |
| parents | 93147b89ea67 |
| children | ae5ac41c391d |
| rev | line source |
|---|---|
|
3794
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 -- |
|
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
3 -- Copyright (c) 2019-2020 Kim Alvefur |
|
3794
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 |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
7 local encodings = require "util.encodings"; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
8 local base64 = encodings.base64; |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
9 local errors = require "util.error"; |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
10 local http = require "net.http"; |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
11 local id = require "util.id"; |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
12 local jid = require "util.jid"; |
| 3813 | 13 local json = require "util.json"; |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
14 local st = require "util.stanza"; |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
15 local um = require "core.usermanager"; |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
16 local xml = require "util.xml"; |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
17 |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
18 local jsonmap = module:require"jsonmap"; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
19 |
|
3915
80dffbbd056b
mod_rest, mod_http_oauth2: Switch from mod_authtokens to mod_tokenauth per Prosody bf81523e2ff4
Matthew Wild <mwild1@gmail.com>
parents:
3911
diff
changeset
|
20 local tokens = module:depends("tokenauth"); |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
21 |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
22 local auth_mechanisms = module:get_option_set("rest_auth_mechanisms", { "Basic", "Bearer" }); |
|
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
23 |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
24 local www_authenticate_header; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
25 do |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
26 local header, realm = {}, module.host.."/"..module.name; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
27 for mech in auth_mechanisms do |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
28 header[#header+1] = ("%s realm=%q"):format(mech, realm); |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
29 end |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
30 www_authenticate_header = table.concat(header, ", "); |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
31 end |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
32 |
|
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
33 -- Bearer token |
|
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
34 local function check_credentials(request) |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
35 local auth_type, auth_data = string.match(request.headers.authorization, "^(%S+)%s(.+)$"); |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
36 if not (auth_type and auth_data) or not auth_mechanisms:contains(auth_type) then |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
37 return false; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
38 end |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
39 |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
40 if auth_type == "Basic" then |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
41 local creds = base64.decode(auth_data); |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
42 if not creds then return false; end |
|
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
43 local username, password = string.match(creds, "^([^:]+):(.*)$"); |
|
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
44 if not username then return false; end |
|
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
45 username, password = encodings.stringprep.nodeprep(username), encodings.stringprep.saslprep(password); |
|
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
46 if not username then return false; end |
|
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
47 if not um.test_password(username, module.host, password) then |
|
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
48 return false; |
|
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
49 end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
50 return { username = username, host = module.host }; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
51 elseif auth_type == "Bearer" then |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
52 local token_info = tokens.get_token_info(auth_data); |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
53 if not token_info or not token_info.session then |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
54 return false; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
55 end |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
56 return token_info.session; |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
57 end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
58 return nil; |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
59 end |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
60 |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
61 local function parse(mimetype, data) |
|
3825
802087d3155a
mod_rest: Fix traceback on missing content-type header
Kim Alvefur <zash@zash.se>
parents:
3824
diff
changeset
|
62 mimetype = mimetype and mimetype:match("^[^; ]*"); |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
63 if mimetype == "application/xmpp+xml" then |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
64 return xml.parse(data); |
| 3813 | 65 elseif mimetype == "application/json" then |
| 66 local parsed, err = json.decode(data); | |
| 67 if not parsed then | |
| 68 return parsed, err; | |
| 69 end | |
| 70 return jsonmap.json2st(parsed); | |
|
3911
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
71 elseif mimetype == "application/x-www-form-urlencoded"then |
|
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
72 local parsed = http.formdecode(data); |
|
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
73 if type(parsed) == "string" then |
|
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
74 return parse("text/plain", parsed); |
|
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
75 end |
|
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
76 for i = #parsed, 1, -1 do |
|
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
77 parsed[i] = nil; |
|
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
78 end |
|
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
79 return jsonmap.json2st(parsed); |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
80 elseif mimetype == "text/plain" then |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
81 return st.message({ type = "chat" }, data); |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
82 end |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
83 return nil, "unknown-payload-type"; |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
84 end |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
85 |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
86 local function decide_type(accept, supported_types) |
| 3813 | 87 -- assumes the accept header is sorted |
| 88 local ret = supported_types[1]; | |
| 89 for i = 2, #supported_types do | |
| 90 if (accept:find(supported_types[i], 1, true) or 1000) < (accept:find(ret, 1, true) or 1000) then | |
| 91 ret = supported_types[i]; | |
| 92 end | |
| 93 end | |
| 94 return ret; | |
|
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
95 end |
|
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
96 |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
97 local supported_inputs = { |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
98 "application/xmpp+xml", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
99 "application/json", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
100 "application/x-www-form-urlencoded", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
101 "text/plain", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
102 }; |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
103 |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
104 local supported_outputs = { |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
105 "application/xmpp+xml", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
106 "application/json", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
107 }; |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
108 |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
109 local function encode(type, s) |
| 3813 | 110 if type == "application/json" then |
| 111 return json.encode(jsonmap.st2json(s)); | |
| 112 elseif type == "text/plain" then | |
| 113 return s:get_child_text("body") or ""; | |
| 114 end | |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
115 return tostring(s); |
|
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
116 end |
|
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
117 |
|
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
118 local post_errors = { |
|
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
119 parse = { code = 400, condition = "not-well-formed", text = "Failed to parse payload", }, |
|
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
120 xmlns = { code = 422, condition = "invalid-namespace", text = "'xmlns' attribute must be empty", }, |
|
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
121 name = { code = 422, condition = "unsupported-stanza-type", text = "Invalid stanza, must be 'message', 'presence' or 'iq'.", }, |
|
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
122 to = { code = 422, condition = "improper-addressing", text = "Invalid destination JID", }, |
|
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
123 from = { code = 422, condition = "invalid-from", text = "Invalid source JID", }, |
|
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
124 post_auth = { code = 403, condition = "not-authorized", text = "Not authorized to send stanza with requested 'from'", }, |
|
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
125 iq_type = { code = 422, condition = "invalid-xml", text = "'iq' stanza must be of type 'get' or 'set'", }, |
|
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
126 iq_tags = { code = 422, condition = "bad-format", text = "'iq' stanza must have exactly one child tag", }, |
|
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
127 }; |
|
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
128 |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
129 local function handle_post(event) |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
130 local request, response = event.request, event.response; |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
131 local from; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
132 local origin; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
133 |
|
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
134 if not request.headers.authorization then |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
135 response.headers.www_authenticate = www_authenticate_header; |
|
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
136 return 401; |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
137 else |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
138 origin = check_credentials(request); |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
139 if not origin then |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
140 return 401; |
|
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
141 end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
142 from = jid.join(origin.username, origin.host, origin.resource); |
|
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
143 end |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
144 local payload, err = parse(request.headers.content_type, request.body); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
145 if not payload then |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
146 -- parse fail |
|
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
147 return errors.new("parse", { error = err, type = request.headers.content_type, data = request.body, }, post_errors); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
148 end |
|
3801
d59fb4dcf100
mod_rest: Verify that @xmlns is left empty
Kim Alvefur <zash@zash.se>
parents:
3799
diff
changeset
|
149 if payload.attr.xmlns then |
|
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
150 return errors.new("xmlns", nil, post_errors); |
|
3805
683b06c0348f
mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents:
3804
diff
changeset
|
151 elseif payload.name ~= "message" and payload.name ~= "presence" and payload.name ~= "iq" then |
|
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
152 return errors.new("name", nil, post_errors); |
|
3801
d59fb4dcf100
mod_rest: Verify that @xmlns is left empty
Kim Alvefur <zash@zash.se>
parents:
3799
diff
changeset
|
153 end |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
154 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
|
155 if not to then |
|
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
156 return errors.new("to", nil, post_errors); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
157 end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
158 if payload.attr.from then |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
159 local requested_from = jid.prep(payload.attr.from); |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
160 if not requested_from then |
|
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
161 return errors.new("from", nil, post_errors); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
162 end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
163 if jid.compare(requested_from, from) then |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
164 from = requested_from; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
165 else |
|
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
166 return errors.new("from_auth", nil, post_errors); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
167 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
168 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
169 payload.attr = { |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
170 from = from, |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
171 to = to, |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
172 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
|
173 type = payload.attr.type, |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
174 ["xml:lang"] = payload.attr["xml:lang"], |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
175 }; |
|
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
176 module:log("debug", "Received[rest]: %s", payload:top_tag()); |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
177 local send_type = decide_type((request.headers.accept or "") ..",".. request.headers.content_type, supported_outputs) |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
178 if payload.name == "iq" then |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
179 function origin.send(stanza) |
|
3926
f77ae9685eb6
mod_rest: Fix routing to self-jid (thanks jonas’)
Kim Alvefur <zash@zash.se>
parents:
3925
diff
changeset
|
180 module:send(stanza); |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
181 end |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
182 if payload.attr.type ~= "get" and payload.attr.type ~= "set" then |
|
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
183 return errors.new("iq_type", nil, post_errors); |
|
3832
0d4146cf9fbc
mod_rest: Enforce single child policy for outgoing it stanzas
Kim Alvefur <zash@zash.se>
parents:
3825
diff
changeset
|
184 elseif #payload.tags ~= 1 then |
|
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
185 return errors.new("iq_tags", nil, post_errors); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
186 end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
187 return module:send_iq(payload, origin):next( |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
188 function (result) |
|
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
189 module:log("debug", "Sending[rest]: %s", result.stanza:top_tag()); |
|
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
190 response.headers.content_type = send_type; |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
191 return encode(send_type, result.stanza); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
192 end, |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
193 function (error) |
|
3909
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
194 if not errors.is_err(error) then |
|
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
195 module:log("error", "Uncaught native error: %s", error); |
|
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
196 return select(2, errors.coerce(nil, error)); |
|
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
197 elseif error.context and error.context.stanza then |
|
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
198 response.headers.content_type = send_type; |
|
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
199 module:log("debug", "Sending[rest]: %s", error.context.stanza:top_tag()); |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
200 return encode(send_type, error.context.stanza); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
201 else |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
202 return error; |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
203 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
204 end); |
|
3805
683b06c0348f
mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents:
3804
diff
changeset
|
205 else |
|
3796
d1ad10b76b00
mod_rest: Catch one (1) reply to a POST-ed stanza from an internal source
Kim Alvefur <zash@zash.se>
parents:
3795
diff
changeset
|
206 function origin.send(stanza) |
|
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
207 module:log("debug", "Sending[rest]: %s", stanza:top_tag()); |
|
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
208 response.headers.content_type = send_type; |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
209 response:send(encode(send_type, stanza)); |
|
3796
d1ad10b76b00
mod_rest: Catch one (1) reply to a POST-ed stanza from an internal source
Kim Alvefur <zash@zash.se>
parents:
3795
diff
changeset
|
210 return true; |
|
d1ad10b76b00
mod_rest: Catch one (1) reply to a POST-ed stanza from an internal source
Kim Alvefur <zash@zash.se>
parents:
3795
diff
changeset
|
211 end |
|
3814
0dede5b0ab27
mod_rest: Fix return status when sending and forgetting
Kim Alvefur <zash@zash.se>
parents:
3813
diff
changeset
|
212 module:send(payload, origin); |
|
0dede5b0ab27
mod_rest: Fix return status when sending and forgetting
Kim Alvefur <zash@zash.se>
parents:
3813
diff
changeset
|
213 return 202; |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
214 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
215 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
216 |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
217 -- Handle stanzas submitted via HTTP |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
218 module:depends("http"); |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
219 module:provides("http", { |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
220 route = { |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
221 POST = handle_post; |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
222 }; |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
223 }); |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
224 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
225 -- 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:
3794
diff
changeset
|
226 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:
3794
diff
changeset
|
227 if rest_url then |
|
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
228 local send_type = module:get_option_string("rest_callback_content_type", "application/xmpp+xml"); |
| 3813 | 229 if send_type == "json" then |
| 230 send_type = "application/json"; | |
| 231 end | |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
232 |
|
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
233 module:set_status("info", "Not yet connected"); |
|
3861
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
234 http.request(rest_url, { |
|
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
235 method = "OPTIONS", |
|
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
236 }, function (body, code, response) |
|
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
237 if code == 0 then |
|
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
238 return module:log_status("error", "Could not connect to callback URL %q: %s", rest_url, body); |
|
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
239 else |
|
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
240 module:set_status("info", "Connected"); |
|
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
241 end |
|
3861
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
242 if code == 200 and response.headers.accept then |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
243 send_type = decide_type(response.headers.accept, supported_outputs); |
|
3861
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
244 module:log("debug", "Set 'rest_callback_content_type' = %q based on Accept header", send_type); |
|
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
245 end |
|
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
246 end); |
|
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
247 |
|
3797
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
248 local code2err = { |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
249 [400] = { condition = "bad-request"; type = "modify" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
250 [401] = { condition = "not-authorized"; type = "auth" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
251 [402] = { condition = "not-authorized"; type = "auth" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
252 [403] = { condition = "forbidden"; type = "auth" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
253 [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:
3796
diff
changeset
|
254 [406] = { condition = "not-acceptable"; type = "modify" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
255 [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:
3796
diff
changeset
|
256 [409] = { condition = "conflict"; type = "cancel" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
257 [410] = { condition = "gone"; type = "cancel" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
258 [411] = { condition = "bad-request"; type = "modify" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
259 [412] = { condition = "bad-request"; type = "modify" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
260 [413] = { condition = "resource-constraint"; type = "modify" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
261 [414] = { condition = "resource-constraint"; type = "modify" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
262 [415] = { condition = "bad-request"; type = "modify" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
263 [429] = { condition = "resource-constraint"; type = "wait" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
264 [431] = { condition = "resource-constraint"; type = "wait" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
265 |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
266 [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:
3796
diff
changeset
|
267 [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:
3796
diff
changeset
|
268 [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:
3796
diff
changeset
|
269 [503] = { condition = "service-unavailable"; type = "cancel" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
270 [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:
3796
diff
changeset
|
271 [507] = { condition = "resource-constraint"; type = "wait" }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
272 }; |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
273 |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
274 local function handle_stanza(event) |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
275 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:
3794
diff
changeset
|
276 local reply_needed = stanza.name == "iq"; |
|
3798
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
277 local receipt; |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
278 |
|
3824
a0b8ec44a36b
mod_rest: Stanzas of type error don't need a reply
Kim Alvefur <zash@zash.se>
parents:
3821
diff
changeset
|
279 if stanza.attr.type == "error" then |
|
a0b8ec44a36b
mod_rest: Stanzas of type error don't need a reply
Kim Alvefur <zash@zash.se>
parents:
3821
diff
changeset
|
280 reply_needed = false; |
|
a0b8ec44a36b
mod_rest: Stanzas of type error don't need a reply
Kim Alvefur <zash@zash.se>
parents:
3821
diff
changeset
|
281 end |
|
a0b8ec44a36b
mod_rest: Stanzas of type error don't need a reply
Kim Alvefur <zash@zash.se>
parents:
3821
diff
changeset
|
282 |
|
3798
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
283 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:
3797
diff
changeset
|
284 reply_needed = true; |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
285 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:
3797
diff
changeset
|
286 end |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
287 |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
288 local request_body = encode(send_type, stanza); |
|
3799
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
289 |
|
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
290 -- 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:
3798
diff
changeset
|
291 stanza = st.clone(stanza, true); |
|
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
292 |
|
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
293 module:log("debug", "Sending[rest]: %s", stanza:top_tag()); |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
294 http.request(rest_url, { |
|
3799
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
295 body = request_body, |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
296 headers = { |
|
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
297 ["Content-Type"] = send_type, |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
298 ["Content-Language"] = stanza.attr["xml:lang"], |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
299 Accept = table.concat(supported_inputs, ", "); |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
300 }, |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
301 }, function (body, code, response) |
|
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
302 if code == 0 then |
|
3864
d845475c75f3
mod_rest: Process results even on internal errors with HTTP request
Kim Alvefur <zash@zash.se>
parents:
3862
diff
changeset
|
303 module:log_status("error", "Could not connect to callback URL %q: %s", rest_url, body); |
|
3866
c0df50ce96f0
mod_rest: Handle internal http request errors early and then return
Kim Alvefur <zash@zash.se>
parents:
3865
diff
changeset
|
304 origin.send(st.error_reply(stanza, "wait", "recipient-unavailable", body)); |
|
c0df50ce96f0
mod_rest: Handle internal http request errors early and then return
Kim Alvefur <zash@zash.se>
parents:
3865
diff
changeset
|
305 return; |
|
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
306 else |
|
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
307 module:set_status("info", "Connected"); |
|
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
308 end |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
309 local reply; |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
310 |
|
3867
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
311 if code == 202 or code == 204 then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
312 if not reply_needed then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
313 -- Delivered, no reply |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
314 return; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
315 end |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
316 else |
|
3867
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
317 local parsed, err = parse(response.headers["content-type"], body); |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
318 if not parsed then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
319 module:log("warn", "Failed parsing data from REST callback: %s, %q", err, body); |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
320 elseif parsed.name ~= stanza.name then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
321 module:log("warn", "REST callback responded with the wrong stanza type, got %s but expected %s", parsed.name, stanza.name); |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
322 else |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
323 parsed.attr = { |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
324 from = stanza.attr.to, |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
325 to = stanza.attr.from, |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
326 id = parsed.attr.id or id.medium(); |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
327 type = parsed.attr.type, |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
328 ["xml:lang"] = parsed.attr["xml:lang"], |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
329 }; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
330 if parsed.name == "message" and parsed.attr.type == "groupchat" then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
331 parsed.attr.to = jid.bare(stanza.attr.from); |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
332 end |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
333 if not stanza.attr.type and parsed:get_child("error") then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
334 parsed.attr.type = "error"; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
335 end |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
336 if parsed.attr.type == "error" then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
337 parsed.attr.id = stanza.attr.id; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
338 elseif parsed.name == "iq" then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
339 parsed.attr.id = stanza.attr.id; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
340 parsed.attr.type = "result"; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
341 end |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
342 reply = parsed; |
|
3821
11272a3233ce
mod_rest: Fix replying to groupchat messages
Kim Alvefur <zash@zash.se>
parents:
3816
diff
changeset
|
343 end |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
344 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
345 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
346 if not reply then |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
347 local code_hundreds = code - (code % 100); |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
348 if code_hundreds == 200 then |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
349 reply = st.reply(stanza); |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
350 if stanza.name ~= "iq" then |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
351 reply.attr.id = id.medium(); |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
352 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
353 -- TODO presence/status=body ? |
|
3797
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
354 elseif code2err[code] then |
|
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
355 reply = st.error_reply(stanza, errors.new(code, nil, code2err)); |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
356 elseif code_hundreds == 400 then |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
357 reply = st.error_reply(stanza, "modify", "bad-request", body); |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
358 elseif code_hundreds == 500 then |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
359 reply = st.error_reply(stanza, "cancel", "internal-server-error", body); |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
360 else |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
361 reply = st.error_reply(stanza, "cancel", "undefined-condition", body); |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
362 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
363 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
364 |
|
3798
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
365 if receipt then |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
366 reply:add_direct_child(receipt); |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
367 end |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
368 |
|
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
369 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:
3802
diff
changeset
|
370 |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
371 origin.send(reply); |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
372 end); |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
373 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
374 return true; |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
375 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
376 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
377 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:
3794
diff
changeset
|
378 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:
3794
diff
changeset
|
379 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:
3794
diff
changeset
|
380 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:
3794
diff
changeset
|
381 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:
3794
diff
changeset
|
382 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:
3794
diff
changeset
|
383 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:
3794
diff
changeset
|
384 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:
3794
diff
changeset
|
385 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:
3794
diff
changeset
|
386 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:
3794
diff
changeset
|
387 else |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
388 -- 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:
3794
diff
changeset
|
389 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:
3794
diff
changeset
|
390 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:
3794
diff
changeset
|
391 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:
3794
diff
changeset
|
392 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
393 end |
|
3842
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3832
diff
changeset
|
394 |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
395 local supported_errors = { |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
396 "text/html", |
|
3931
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
397 "application/xmpp+xml", |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
398 "application/json", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
399 }; |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
400 |
|
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
401 local http_server = require "net.http.server"; |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
402 module:hook_object_event(http_server, "http-error", function (event) |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
403 local request, response = event.request, event.response; |
|
3931
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
404 local response_as = decide_type(request and request.headers.accept or "", supported_errors); |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
405 if response_as == "application/xmpp+xml" then |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
406 if response then |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
407 response.headers.content_type = "application/xmpp+xml"; |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
408 end |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
409 local stream_error = st.stanza("error", { xmlns = "http://etherx.jabber.org/streams" }); |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
410 if event.error then |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
411 stream_error:tag(event.error.condition, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' }):up(); |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
412 if event.error.text then |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
413 stream_error:text_tag("text", event.error.text, {xmlns = 'urn:ietf:params:xml:ns:xmpp-streams' }); |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
414 end |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
415 end |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
416 return tostring(stream_error); |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
417 elseif response_as == "application/json" then |
|
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
418 if response then |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
419 response.headers.content_type = "application/json"; |
|
3842
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3832
diff
changeset
|
420 end |
|
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
421 return json.encode({ |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
422 type = "error", |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
423 error = event.error, |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
424 code = event.code, |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
425 }); |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
426 end |
|
3933
93147b89ea67
mod_rest: Avoid interfering with mod_http_oauth2 errors (fixes #1500)
Kim Alvefur <zash@zash.se>
parents:
3931
diff
changeset
|
427 end, 1); |
