Software / code / prosody-modules
Annotate
mod_rest/mod_rest.lua @ 4330:e655581173be
mod_cloud_notify_encrypted: Fixes to the push notification syntax and payload
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Wed, 13 Jan 2021 14:18:24 +0000 |
| parent | 4250:8b489203e4d3 |
| child | 4477:8df6cc648963 |
| 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"; |
| 4037 | 17 local have_cbor, cbor = pcall(require, "cbor"); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
18 |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
19 local jsonmap = module:require"jsonmap"; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
20 |
|
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
|
21 local tokens = module:depends("tokenauth"); |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
22 |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
23 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
|
24 |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
25 local www_authenticate_header; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
26 do |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
27 local header, realm = {}, module.host.."/"..module.name; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
28 for mech in auth_mechanisms do |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
29 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
|
30 end |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
31 www_authenticate_header = table.concat(header, ", "); |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
32 end |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
33 |
|
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
34 -- Bearer token |
|
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
35 local function check_credentials(request) |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
36 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
|
37 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
|
38 return false; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
39 end |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
40 |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
41 if auth_type == "Basic" then |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
42 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
|
43 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
|
44 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
|
45 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
|
46 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
|
47 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
|
48 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
|
49 return false; |
|
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
50 end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
51 return { username = username, host = module.host }; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
52 elseif auth_type == "Bearer" then |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
53 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
|
54 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
|
55 return false; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
56 end |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
57 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
|
58 end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
59 return nil; |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
60 end |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
61 |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
62 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
|
63 mimetype = mimetype and mimetype:match("^[^; ]*"); |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
64 if mimetype == "application/xmpp+xml" then |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
65 return xml.parse(data); |
| 3813 | 66 elseif mimetype == "application/json" then |
| 67 local parsed, err = json.decode(data); | |
| 68 if not parsed then | |
| 69 return parsed, err; | |
| 70 end | |
| 71 return jsonmap.json2st(parsed); | |
| 4037 | 72 elseif mimetype == "application/cbor" and have_cbor then |
| 73 local parsed, err = cbor.decode(data); | |
| 74 if not parsed then | |
| 75 return parsed, err; | |
| 76 end | |
| 77 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
|
78 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
|
79 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
|
80 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
|
81 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
|
82 end |
|
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
83 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
|
84 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
|
85 end |
|
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
86 return jsonmap.json2st(parsed); |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
87 elseif mimetype == "text/plain" then |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
88 return st.message({ type = "chat" }, data); |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
89 end |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
90 return nil, "unknown-payload-type"; |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
91 end |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
92 |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
93 local function decide_type(accept, supported_types) |
| 3813 | 94 -- assumes the accept header is sorted |
| 95 local ret = supported_types[1]; | |
| 96 for i = 2, #supported_types do | |
| 97 if (accept:find(supported_types[i], 1, true) or 1000) < (accept:find(ret, 1, true) or 1000) then | |
| 98 ret = supported_types[i]; | |
| 99 end | |
| 100 end | |
| 101 return ret; | |
|
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
102 end |
|
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
103 |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
104 local supported_inputs = { |
|
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 "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
|
108 "text/plain", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
109 }; |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
110 |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
111 local supported_outputs = { |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
112 "application/xmpp+xml", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
113 "application/json", |
|
4066
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
114 "application/x-www-form-urlencoded", |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
115 }; |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
116 |
| 4037 | 117 if have_cbor then |
| 118 table.insert(supported_inputs, "application/cbor"); | |
| 119 table.insert(supported_outputs, "application/cbor"); | |
| 120 end | |
| 121 | |
|
4066
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
122 -- Only { string : string } can be form-encoded, discard the rest |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
123 -- (jsonmap also discards anything unknown or unsupported) |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
124 local function flatten(t) |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
125 local form = {}; |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
126 for k, v in pairs(t) do |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
127 if type(v) == "string" then |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
128 form[k] = v; |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
129 elseif type(v) == "number" then |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
130 form[k] = tostring(v); |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
131 elseif v == true then |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
132 form[k] = ""; |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
133 end |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
134 end |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
135 return form; |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
136 end |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
137 |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
138 local function encode(type, s) |
| 3813 | 139 if type == "application/json" then |
| 140 return json.encode(jsonmap.st2json(s)); | |
|
4066
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
141 elseif type == "application/x-www-form-urlencoded" then |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
142 return http.formencode(flatten(jsonmap.st2json(s))); |
| 4037 | 143 elseif type == "application/cbor" then |
| 144 return cbor.encode(jsonmap.st2json(s)); | |
| 3813 | 145 elseif type == "text/plain" then |
| 146 return s:get_child_text("body") or ""; | |
| 147 end | |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
148 return tostring(s); |
|
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
149 end |
|
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
150 |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
151 local post_errors = errors.init("mod_rest", { |
|
3971
ae5ac41c391d
mod_rest: Improve auth error reporting
Kim Alvefur <zash@zash.se>
parents:
3933
diff
changeset
|
152 noauthz = { code = 401, type = "auth", condition = "not-authorized", text = "No credentials provided" }, |
|
ae5ac41c391d
mod_rest: Improve auth error reporting
Kim Alvefur <zash@zash.se>
parents:
3933
diff
changeset
|
153 unauthz = { code = 403, type = "auth", condition = "not-authorized", text = "Credentials not accepted" }, |
|
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
154 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
|
155 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
|
156 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
|
157 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
|
158 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
|
159 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
|
160 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
|
161 iq_tags = { code = 422, condition = "bad-format", text = "'iq' stanza must have exactly one child tag", }, |
|
4036
04c11b652aeb
mod_rest: Respond to unknown payload types with HTTP status 415
Kim Alvefur <zash@zash.se>
parents:
3971
diff
changeset
|
162 mediatype = { code = 415, condition = "bad-format", text = "Unsupported media type" }, |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
163 }); |
|
3930
d5dafd617cd6
mod_rest: Break out POST errors into a registry
Kim Alvefur <zash@zash.se>
parents:
3929
diff
changeset
|
164 |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
165 local function handle_post(event) |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
166 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
|
167 local from; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
168 local origin; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
169 |
|
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
170 if not request.headers.authorization then |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
171 response.headers.www_authenticate = www_authenticate_header; |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
172 return post_errors.new("noauthz"); |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
173 else |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
174 origin = check_credentials(request); |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
175 if not origin then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
176 return post_errors.new("unauthz"); |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
177 end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
178 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
|
179 end |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
180 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
|
181 if not payload then |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
182 -- parse fail |
|
4036
04c11b652aeb
mod_rest: Respond to unknown payload types with HTTP status 415
Kim Alvefur <zash@zash.se>
parents:
3971
diff
changeset
|
183 local ctx = { error = err, type = request.headers.content_type, data = request.body, }; |
|
04c11b652aeb
mod_rest: Respond to unknown payload types with HTTP status 415
Kim Alvefur <zash@zash.se>
parents:
3971
diff
changeset
|
184 if err == "unknown-payload-type" then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
185 return post_errors.new("mediatype", ctx); |
|
4036
04c11b652aeb
mod_rest: Respond to unknown payload types with HTTP status 415
Kim Alvefur <zash@zash.se>
parents:
3971
diff
changeset
|
186 end |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
187 return post_errors.new("parse", ctx); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
188 end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
189 |
|
3801
d59fb4dcf100
mod_rest: Verify that @xmlns is left empty
Kim Alvefur <zash@zash.se>
parents:
3799
diff
changeset
|
190 if payload.attr.xmlns then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
191 return post_errors.new("xmlns"); |
|
3805
683b06c0348f
mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents:
3804
diff
changeset
|
192 elseif payload.name ~= "message" and payload.name ~= "presence" and payload.name ~= "iq" then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
193 return post_errors.new("name"); |
|
3801
d59fb4dcf100
mod_rest: Verify that @xmlns is left empty
Kim Alvefur <zash@zash.se>
parents:
3799
diff
changeset
|
194 end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
195 |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
196 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
|
197 if not to then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
198 return post_errors.new("to"); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
199 end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
200 |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
201 if payload.attr.from then |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
202 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
|
203 if not requested_from then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
204 return post_errors.new("from"); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
205 end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
206 if jid.compare(requested_from, from) then |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
207 from = requested_from; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
208 else |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
209 return post_errors.new("from_auth"); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
210 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
211 end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
212 |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
213 payload.attr = { |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
214 from = from, |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
215 to = to, |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
216 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
|
217 type = payload.attr.type, |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
218 ["xml:lang"] = payload.attr["xml:lang"], |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
219 }; |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
220 |
|
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
221 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
|
222 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
|
223 if payload.name == "iq" then |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
224 function origin.send(stanza) |
|
3926
f77ae9685eb6
mod_rest: Fix routing to self-jid (thanks jonas’)
Kim Alvefur <zash@zash.se>
parents:
3925
diff
changeset
|
225 module:send(stanza); |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
226 end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
227 |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
228 if payload.attr.type ~= "get" and payload.attr.type ~= "set" then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
229 return post_errors.new("iq_type"); |
|
3832
0d4146cf9fbc
mod_rest: Enforce single child policy for outgoing it stanzas
Kim Alvefur <zash@zash.se>
parents:
3825
diff
changeset
|
230 elseif #payload.tags ~= 1 then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
231 return post_errors.new("iq_tags"); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
232 end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
233 |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
234 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
|
235 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
|
236 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
|
237 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
|
238 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
|
239 end, |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
240 function (error) |
|
3909
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
241 if not errors.is_err(error) then |
|
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
242 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
|
243 return select(2, errors.coerce(nil, error)); |
|
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
244 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
|
245 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
|
246 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
|
247 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
|
248 else |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
249 return error; |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
250 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
251 end); |
|
3805
683b06c0348f
mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents:
3804
diff
changeset
|
252 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
|
253 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
|
254 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
|
255 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
|
256 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
|
257 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
|
258 end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
259 |
|
3814
0dede5b0ab27
mod_rest: Fix return status when sending and forgetting
Kim Alvefur <zash@zash.se>
parents:
3813
diff
changeset
|
260 module:send(payload, origin); |
|
0dede5b0ab27
mod_rest: Fix return status when sending and forgetting
Kim Alvefur <zash@zash.se>
parents:
3813
diff
changeset
|
261 return 202; |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
262 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
263 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
264 |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
265 -- Handle stanzas submitted via HTTP |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
266 module:depends("http"); |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
267 module:provides("http", { |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
268 route = { |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
269 POST = handle_post; |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
270 }; |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
271 }); |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
272 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
273 -- 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
|
274 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
|
275 if rest_url then |
|
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
276 local send_type = module:get_option_string("rest_callback_content_type", "application/xmpp+xml"); |
| 3813 | 277 if send_type == "json" then |
| 278 send_type = "application/json"; | |
| 279 end | |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
280 |
|
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
281 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
|
282 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
|
283 method = "OPTIONS", |
|
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
284 }, function (body, code, response) |
|
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
285 if code == 0 then |
|
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
286 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
|
287 else |
|
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
288 module:set_status("info", "Connected"); |
|
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
289 end |
|
3861
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
290 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
|
291 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
|
292 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
|
293 end |
|
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
294 end); |
|
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
295 |
|
4245
7bf3bf81c9ef
mod_rest: Use HTTP error mapping from net.http.errors
Kim Alvefur <zash@zash.se>
parents:
4244
diff
changeset
|
296 local code2err = require "net.http.errors".registry; |
|
3797
ed5d7586a61e
mod_rest: Map various HTTP status codes to XMPP stanza errors
Kim Alvefur <zash@zash.se>
parents:
3796
diff
changeset
|
297 |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
298 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
|
299 local stanza, origin = event.stanza, event.origin; |
|
4250
8b489203e4d3
mod_rest: Ensure no attempt is made to reply to an error stanza
Kim Alvefur <zash@zash.se>
parents:
4249
diff
changeset
|
300 local reply_allowed = stanza.attr.type ~= "error"; |
|
8b489203e4d3
mod_rest: Ensure no attempt is made to reply to an error stanza
Kim Alvefur <zash@zash.se>
parents:
4249
diff
changeset
|
301 local reply_needed = reply_allowed and stanza.name == "iq"; |
|
3798
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
302 local receipt; |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
303 |
|
4250
8b489203e4d3
mod_rest: Ensure no attempt is made to reply to an error stanza
Kim Alvefur <zash@zash.se>
parents:
4249
diff
changeset
|
304 if reply_allowed and stanza.name == "message" and stanza.attr.id and stanza:get_child("urn:xmpp:receipts", "request") then |
|
3798
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
305 reply_needed = true; |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
306 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
|
307 end |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
308 |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
309 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
|
310 |
|
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
311 -- 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
|
312 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
|
313 |
|
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
314 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
|
315 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
|
316 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
|
317 headers = { |
|
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
318 ["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
|
319 ["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
|
320 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
|
321 }, |
|
4247
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
322 }):next(function (response) |
|
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
323 module:set_status("info", "Connected"); |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
324 local reply; |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
325 |
|
4247
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
326 local code, body = response.code, response.body; |
|
4250
8b489203e4d3
mod_rest: Ensure no attempt is made to reply to an error stanza
Kim Alvefur <zash@zash.se>
parents:
4249
diff
changeset
|
327 if not reply_allowed then |
|
8b489203e4d3
mod_rest: Ensure no attempt is made to reply to an error stanza
Kim Alvefur <zash@zash.se>
parents:
4249
diff
changeset
|
328 return; |
|
8b489203e4d3
mod_rest: Ensure no attempt is made to reply to an error stanza
Kim Alvefur <zash@zash.se>
parents:
4249
diff
changeset
|
329 elseif code == 202 or code == 204 then |
|
3867
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
330 if not reply_needed then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
331 -- Delivered, no reply |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
332 return; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
333 end |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
334 else |
|
3867
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
335 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
|
336 if not parsed then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
337 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
|
338 elseif parsed.name ~= stanza.name then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
339 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
|
340 else |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
341 parsed.attr = { |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
342 from = stanza.attr.to, |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
343 to = stanza.attr.from, |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
344 id = parsed.attr.id or id.medium(); |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
345 type = parsed.attr.type, |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
346 ["xml:lang"] = parsed.attr["xml:lang"], |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
347 }; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
348 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
|
349 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
|
350 end |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
351 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
|
352 parsed.attr.type = "error"; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
353 end |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
354 if parsed.attr.type == "error" then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
355 parsed.attr.id = stanza.attr.id; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
356 elseif parsed.name == "iq" then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
357 parsed.attr.id = stanza.attr.id; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
358 parsed.attr.type = "result"; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
359 end |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
360 reply = parsed; |
|
3821
11272a3233ce
mod_rest: Fix replying to groupchat messages
Kim Alvefur <zash@zash.se>
parents:
3816
diff
changeset
|
361 end |
|
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 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
364 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
|
365 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
|
366 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
|
367 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
|
368 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
|
369 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
|
370 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
371 -- 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
|
372 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
|
373 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
|
374 elseif code_hundreds == 400 then |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
375 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
|
376 elseif code_hundreds == 500 then |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
377 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
|
378 else |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
379 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
|
380 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
381 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
382 |
|
3798
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
383 if receipt then |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
384 reply:add_direct_child(receipt); |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
385 end |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
386 |
|
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
387 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
|
388 |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
389 origin.send(reply); |
|
4247
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
390 end, |
|
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
391 function (err) |
|
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
392 module:log_status("error", "Could not connect to callback URL %q: %s", rest_url, err); |
|
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
393 origin.send(st.error_reply(stanza, "wait", "recipient-unavailable", err.text)); |
|
4249
64aa1d9d70ac
mod_rest: Catch and log errors in callback promise chain
Kim Alvefur <zash@zash.se>
parents:
4247
diff
changeset
|
394 end):catch(function (err) |
|
64aa1d9d70ac
mod_rest: Catch and log errors in callback promise chain
Kim Alvefur <zash@zash.se>
parents:
4247
diff
changeset
|
395 module:log("error", "Error[rest]: %s", err); |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
396 end); |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
397 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
398 return true; |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
399 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
400 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
401 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
|
402 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
|
403 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
|
404 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
|
405 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
|
406 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
|
407 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
|
408 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
|
409 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
|
410 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
|
411 else |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
412 -- 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
|
413 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
|
414 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
|
415 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
|
416 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
417 end |
|
3842
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3832
diff
changeset
|
418 |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
419 local supported_errors = { |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
420 "text/html", |
|
3931
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
421 "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
|
422 "application/json", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
423 }; |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
424 |
|
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
425 local http_server = require "net.http.server"; |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
426 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
|
427 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
|
428 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
|
429 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
|
430 if response then |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
431 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
|
432 end |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
433 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
|
434 if event.error then |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
435 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
|
436 if event.error.text then |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
437 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
|
438 end |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
439 end |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
440 return tostring(stream_error); |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
441 elseif response_as == "application/json" then |
|
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
442 if response then |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
443 response.headers.content_type = "application/json"; |
|
3842
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3832
diff
changeset
|
444 end |
|
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
445 return json.encode({ |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
446 type = "error", |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
447 error = event.error, |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
448 code = event.code, |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
449 }); |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
450 end |
|
3933
93147b89ea67
mod_rest: Avoid interfering with mod_http_oauth2 errors (fixes #1500)
Kim Alvefur <zash@zash.se>
parents:
3931
diff
changeset
|
451 end, 1); |