Software / code / prosody-modules
Annotate
mod_rest/mod_rest.lua @ 6310:30adcea825c3
mod_conversejs: Fix hostname set as default username (thanks roughnecks)
In login mode, it seems jid is used as default value in the login field
but it was only needed in anonymous mode.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Wed, 18 Jun 2025 14:28:38 +0200 |
| parent | 6272:ed6fa901cf94 |
| 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 -- |
|
4920
bdac7c717c91
mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents:
4918
diff
changeset
|
3 -- Copyright (c) 2019-2022 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 |
|
5701
0cffeff2cd1d
mod_rest: Limit payload size (cf stanza size limits)
Kim Alvefur <zash@zash.se>
parents:
5585
diff
changeset
|
23 -- Lower than the default c2s size limit to account for possible JSON->XML size increase |
|
0cffeff2cd1d
mod_rest: Limit payload size (cf stanza size limits)
Kim Alvefur <zash@zash.se>
parents:
5585
diff
changeset
|
24 local stanza_size_limit = module:get_option_number("rest_stanza_size_limit", 1024 * 192); |
|
0cffeff2cd1d
mod_rest: Limit payload size (cf stanza size limits)
Kim Alvefur <zash@zash.se>
parents:
5585
diff
changeset
|
25 |
|
5960
d5e6617e47cc
mod_rest: Fix to allow case sensitive HTTP authentication scheme
Kim Alvefur <zash@zash.se>
parents:
5954
diff
changeset
|
26 local auth_mechanisms = module:get_option_set("rest_auth_mechanisms", { "Basic", "Bearer" }) / string.lower; |
|
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
27 |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
28 local www_authenticate_header; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
29 do |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
30 local header, realm = {}, module.host.."/"..module.name; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
31 for mech in auth_mechanisms do |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
32 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
|
33 end |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
34 www_authenticate_header = table.concat(header, ", "); |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
35 end |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
36 |
|
5954
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
37 local post_errors = errors.init("mod_rest", { |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
38 noauthz = { code = 401; type = "auth"; condition = "not-authorized"; text = "No credentials provided" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
39 unauthz = { code = 403; type = "auth"; condition = "not-authorized"; text = "Credentials not accepted" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
40 malformauthz = { code = 403; type = "auth"; condition = "not-authorized"; text = "Credentials malformed" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
41 prepauthz = { code = 403; type = "auth"; condition = "not-authorized"; text = "Credentials failed stringprep" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
42 parse = { code = 400; type = "modify"; condition = "not-well-formed"; text = "Failed to parse payload" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
43 xmlns = { code = 422; type = "modify"; condition = "invalid-namespace"; text = "'xmlns' attribute must be empty" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
44 name = { code = 422; type = "modify"; condition = "unsupported-stanza-type"; text = "Invalid stanza, must be 'message', 'presence' or 'iq'." }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
45 to = { code = 422; type = "modify"; condition = "improper-addressing"; text = "Invalid destination JID" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
46 from = { code = 422; type = "modify"; condition = "invalid-from"; text = "Invalid source JID" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
47 from_auth = { code = 403; type = "auth"; condition = "not-authorized"; text = "Not authorized to send stanza with requested 'from'" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
48 iq_type = { code = 422; type = "modify"; condition = "invalid-xml"; text = "'iq' stanza must be of type 'get' or 'set'" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
49 iq_tags = { code = 422; type = "modify"; condition = "bad-format"; text = "'iq' stanza must have exactly one child tag" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
50 mediatype = { code = 415; type = "cancel"; condition = "bad-format"; text = "Unsupported media type" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
51 size = { code = 413; type = "modify"; condition = "resource-constraint", text = "Payload too large" }; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
52 }); |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
53 |
|
5993
a0d77b427d50
mod_rest: Wrap mod_tokenauth errors
Kim Alvefur <zash@zash.se>
parents:
5981
diff
changeset
|
54 local token_session_errors = errors.init("mod_tokenauth", { |
|
a0d77b427d50
mod_rest: Wrap mod_tokenauth errors
Kim Alvefur <zash@zash.se>
parents:
5981
diff
changeset
|
55 ["internal-error"] = { code = 500; type = "wait"; condition = "internal-server-error" }; |
|
a0d77b427d50
mod_rest: Wrap mod_tokenauth errors
Kim Alvefur <zash@zash.se>
parents:
5981
diff
changeset
|
56 ["invalid-token-format"] = { code = 403; type = "auth"; condition = "not-authorized"; text = "Credentials malformed" }; |
|
a0d77b427d50
mod_rest: Wrap mod_tokenauth errors
Kim Alvefur <zash@zash.se>
parents:
5981
diff
changeset
|
57 ["not-authorized"] = { code = 403; type = "auth"; condition = "not-authorized"; text = "Credentials not accepted" }; |
|
a0d77b427d50
mod_rest: Wrap mod_tokenauth errors
Kim Alvefur <zash@zash.se>
parents:
5981
diff
changeset
|
58 }); |
|
a0d77b427d50
mod_rest: Wrap mod_tokenauth errors
Kim Alvefur <zash@zash.se>
parents:
5981
diff
changeset
|
59 |
|
5954
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
60 local function check_credentials(request) -- > session | boolean, error |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
61 local auth_type, auth_data = string.match(request.headers.authorization, "^(%S+)%s(.+)$"); |
| 5962 | 62 auth_type = auth_type and auth_type:lower(); |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
63 if not (auth_type and auth_data) or not auth_mechanisms:contains(auth_type) then |
|
5954
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
64 return nil, post_errors.new("noauthz", { request = request }); |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
65 end |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
66 |
|
6272
ed6fa901cf94
mod_rest: Enable HTTP Basic authentication for Components
Kim Alvefur <zash@zash.se>
parents:
6244
diff
changeset
|
67 if auth_type == "basic" and module:get_host_type() == "local" then |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
68 local creds = base64.decode(auth_data); |
|
5954
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
69 if not creds then |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
70 return nil, post_errors.new("malformauthz", { request = request }); |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
71 end |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
72 local username, password = string.match(creds, "^([^:]+):(.*)$"); |
|
5954
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
73 if not username then |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
74 return nil, post_errors.new("malformauthz", { request = request }); |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
75 end |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
76 username, password = encodings.stringprep.nodeprep(username), encodings.stringprep.saslprep(password); |
|
5954
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
77 if not username or not password then |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
78 return false, post_errors.new("prepauthz", { request = request }); |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
79 end |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
80 if not um.test_password(username, module.host, password) then |
|
5954
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
81 return false, post_errors.new("unauthz", { request = request }); |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
82 end |
|
5954
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
83 return { username = username; host = module.host }; |
|
6272
ed6fa901cf94
mod_rest: Enable HTTP Basic authentication for Components
Kim Alvefur <zash@zash.se>
parents:
6244
diff
changeset
|
84 elseif auth_type == "basic" and module:get_host_type() == "component" then |
|
ed6fa901cf94
mod_rest: Enable HTTP Basic authentication for Components
Kim Alvefur <zash@zash.se>
parents:
6244
diff
changeset
|
85 local component_secret = module:get_option_string("component_secret"); |
|
ed6fa901cf94
mod_rest: Enable HTTP Basic authentication for Components
Kim Alvefur <zash@zash.se>
parents:
6244
diff
changeset
|
86 local creds = base64.decode(auth_data); |
|
ed6fa901cf94
mod_rest: Enable HTTP Basic authentication for Components
Kim Alvefur <zash@zash.se>
parents:
6244
diff
changeset
|
87 if creds ~= module.host .. ":" .. component_secret then |
|
ed6fa901cf94
mod_rest: Enable HTTP Basic authentication for Components
Kim Alvefur <zash@zash.se>
parents:
6244
diff
changeset
|
88 return nil, post_errors.new("malformauthz", { request = request }); |
|
ed6fa901cf94
mod_rest: Enable HTTP Basic authentication for Components
Kim Alvefur <zash@zash.se>
parents:
6244
diff
changeset
|
89 end |
|
ed6fa901cf94
mod_rest: Enable HTTP Basic authentication for Components
Kim Alvefur <zash@zash.se>
parents:
6244
diff
changeset
|
90 return { host = module.host }; |
|
5960
d5e6617e47cc
mod_rest: Fix to allow case sensitive HTTP authentication scheme
Kim Alvefur <zash@zash.se>
parents:
5954
diff
changeset
|
91 elseif auth_type == "bearer" then |
|
5001
cb19cb1c03d6
mod_rest: Update for mod_tokenauth API changes (backwards-compatible)
Matthew Wild <mwild1@gmail.com>
parents:
4988
diff
changeset
|
92 if tokens.get_token_session then |
|
5993
a0d77b427d50
mod_rest: Wrap mod_tokenauth errors
Kim Alvefur <zash@zash.se>
parents:
5981
diff
changeset
|
93 local token_session, err = tokens.get_token_session(auth_data); |
|
a0d77b427d50
mod_rest: Wrap mod_tokenauth errors
Kim Alvefur <zash@zash.se>
parents:
5981
diff
changeset
|
94 if not token_session then |
|
a0d77b427d50
mod_rest: Wrap mod_tokenauth errors
Kim Alvefur <zash@zash.se>
parents:
5981
diff
changeset
|
95 return false, token_session_errors.new(err or "not-authorized", { request = request }); |
|
a0d77b427d50
mod_rest: Wrap mod_tokenauth errors
Kim Alvefur <zash@zash.se>
parents:
5981
diff
changeset
|
96 end |
|
a0d77b427d50
mod_rest: Wrap mod_tokenauth errors
Kim Alvefur <zash@zash.se>
parents:
5981
diff
changeset
|
97 return token_session; |
|
5001
cb19cb1c03d6
mod_rest: Update for mod_tokenauth API changes (backwards-compatible)
Matthew Wild <mwild1@gmail.com>
parents:
4988
diff
changeset
|
98 else -- COMPAT w/0.12 |
|
cb19cb1c03d6
mod_rest: Update for mod_tokenauth API changes (backwards-compatible)
Matthew Wild <mwild1@gmail.com>
parents:
4988
diff
changeset
|
99 local token_info = tokens.get_token_info(auth_data); |
|
cb19cb1c03d6
mod_rest: Update for mod_tokenauth API changes (backwards-compatible)
Matthew Wild <mwild1@gmail.com>
parents:
4988
diff
changeset
|
100 if not token_info or not token_info.session then |
|
5954
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
101 return false, post_errors.new("unauthz", { request = request }); |
|
5001
cb19cb1c03d6
mod_rest: Update for mod_tokenauth API changes (backwards-compatible)
Matthew Wild <mwild1@gmail.com>
parents:
4988
diff
changeset
|
102 end |
|
cb19cb1c03d6
mod_rest: Update for mod_tokenauth API changes (backwards-compatible)
Matthew Wild <mwild1@gmail.com>
parents:
4988
diff
changeset
|
103 return token_info.session; |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
104 end |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
105 end |
|
5954
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
106 return nil, post_errors.new("noauthz", { request = request }); |
|
3876
75b330d4fa6f
mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents:
3874
diff
changeset
|
107 end |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
108 |
|
4734
e58ec4b3cf90
mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents:
4727
diff
changeset
|
109 if module:get_option_string("authentication") == "anonymous" and module:get_option_boolean("anonymous_rest") then |
|
e58ec4b3cf90
mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents:
4727
diff
changeset
|
110 www_authenticate_header = nil; |
|
e58ec4b3cf90
mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents:
4727
diff
changeset
|
111 function check_credentials(request) -- luacheck: ignore 212/request |
|
e58ec4b3cf90
mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents:
4727
diff
changeset
|
112 return { |
|
e58ec4b3cf90
mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents:
4727
diff
changeset
|
113 username = id.medium():lower(); |
|
e58ec4b3cf90
mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents:
4727
diff
changeset
|
114 host = module.host; |
|
e58ec4b3cf90
mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents:
4727
diff
changeset
|
115 } |
|
e58ec4b3cf90
mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents:
4727
diff
changeset
|
116 end |
|
e58ec4b3cf90
mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents:
4727
diff
changeset
|
117 end |
|
e58ec4b3cf90
mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents:
4727
diff
changeset
|
118 |
|
4941
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
119 local function event_suffix(jid_to) |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
120 local node, _, resource = jid.split(jid_to); |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
121 if node then |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
122 if resource then |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
123 return '/full'; |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
124 else |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
125 return '/bare'; |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
126 end |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
127 else |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
128 return '/host'; |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
129 end |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
130 end |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
131 |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
132 |
| 4735 | 133 -- TODO This ought to be handled some way other than duplicating this |
| 134 -- core.stanza_router code here. | |
| 135 local function compat_preevents(origin, stanza) --> boolean : handled | |
| 136 local to = stanza.attr.to; | |
| 137 local node, host, resource = jid.split(to); | |
| 138 | |
| 139 local to_type, to_self; | |
| 140 if node then | |
| 141 if resource then | |
| 142 to_type = '/full'; | |
| 143 else | |
| 144 to_type = '/bare'; | |
| 145 if node == origin.username and host == origin.host then | |
| 146 stanza.attr.to = nil; | |
| 147 to_self = true; | |
| 148 end | |
| 149 end | |
| 150 else | |
| 151 if host then | |
| 152 to_type = '/host'; | |
| 153 else | |
| 154 to_type = '/bare'; | |
| 155 to_self = true; | |
| 156 end | |
| 157 end | |
| 158 | |
| 159 local event_data = { origin = origin; stanza = stanza; to_self = to_self }; | |
| 160 | |
| 161 local result = module:fire_event("pre-stanza", event_data); | |
| 162 if result ~= nil then return true end | |
| 163 if module:fire_event('pre-' .. stanza.name .. to_type, event_data) then return true; end -- do preprocessing | |
| 164 return false | |
| 165 end | |
| 166 | |
|
4477
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
167 -- (table, string) -> table |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
168 local function amend_from_path(data, path) |
|
5981
eef6cb08f9e7
mod_rest: Fix to allow underscores in path of HTTP GET to iq-get mapping
Kim Alvefur <zash@zash.se>
parents:
5962
diff
changeset
|
169 local st_kind, st_type, st_to = path:match("^([mpi]%w+)/([%w_]+)/(.*)$"); |
|
4477
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
170 if not st_kind then return; end |
|
4478
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
171 if st_kind == "iq" and st_type ~= "get" and st_type ~= "set" then |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
172 -- GET /iq/disco/jid |
|
4503
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
173 data = { |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
174 kind = "iq"; |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
175 [st_type] = st_type == "ping" or data or {}; |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
176 }; |
|
4478
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
177 else |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
178 data.kind = st_kind; |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
179 data.type = st_type; |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
180 end |
|
4477
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
181 if st_to and st_to ~= "" then |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
182 data.to = st_to; |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
183 end |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
184 return data; |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
185 end |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
186 |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
187 local function parse(mimetype, data, path) --> Stanza, error enum |
|
3825
802087d3155a
mod_rest: Fix traceback on missing content-type header
Kim Alvefur <zash@zash.se>
parents:
3824
diff
changeset
|
188 mimetype = mimetype and mimetype:match("^[^; ]*"); |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
189 if mimetype == "application/xmpp+xml" then |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
190 return xml.parse(data); |
| 3813 | 191 elseif mimetype == "application/json" then |
| 192 local parsed, err = json.decode(data); | |
| 193 if not parsed then | |
| 194 return parsed, err; | |
| 195 end | |
|
4503
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
196 if path then |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
197 parsed = amend_from_path(parsed, path); |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
198 if not parsed then return nil, "invalid-path"; end |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
199 end |
| 3813 | 200 return jsonmap.json2st(parsed); |
| 4037 | 201 elseif mimetype == "application/cbor" and have_cbor then |
| 202 local parsed, err = cbor.decode(data); | |
| 203 if not parsed then | |
| 204 return parsed, err; | |
| 205 end | |
| 206 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
|
207 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
|
208 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
|
209 if type(parsed) == "string" then |
|
4503
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
210 -- This should reject GET /iq/query/to?messagebody |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
211 if path then |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
212 return nil, "invalid-query"; |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
213 end |
|
3911
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
214 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
|
215 end |
|
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
216 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
|
217 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
|
218 end |
|
4503
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
219 if path then |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
220 parsed = amend_from_path(parsed, path); |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
221 if not parsed then return nil, "invalid-path"; end |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
222 end |
|
3911
064c32a5be7c
mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents:
3910
diff
changeset
|
223 return jsonmap.json2st(parsed); |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
224 elseif mimetype == "text/plain" then |
|
4477
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
225 if not path then |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
226 return st.message({ type = "chat" }, data); |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
227 end |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
228 local parsed = {}; |
|
4503
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
229 if path then |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
230 parsed = amend_from_path(parsed, path); |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
231 if not parsed then return nil, "invalid-path"; end |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
232 end |
|
4477
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
233 if parsed.kind == "message" then |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
234 parsed.body = data; |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
235 elseif parsed.kind == "presence" then |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
236 parsed.show = data; |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
237 else |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
238 return nil, "invalid-path"; |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
239 end |
|
8df6cc648963
mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents:
4250
diff
changeset
|
240 return jsonmap.json2st(parsed); |
|
4478
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
241 elseif not mimetype and path then |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
242 local parsed = amend_from_path({}, path); |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
243 if not parsed then return nil, "invalid-path"; end |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
244 return jsonmap.json2st(parsed); |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
245 end |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
246 return nil, "unknown-payload-type"; |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
247 end |
|
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
248 |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
249 local function decide_type(accept, supported_types) |
| 3813 | 250 -- assumes the accept header is sorted |
| 251 local ret = supported_types[1]; | |
| 252 for i = 2, #supported_types do | |
| 253 if (accept:find(supported_types[i], 1, true) or 1000) < (accept:find(ret, 1, true) or 1000) then | |
| 254 ret = supported_types[i]; | |
| 255 end | |
| 256 end | |
| 257 return ret; | |
|
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
258 end |
|
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
259 |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
260 local supported_inputs = { |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
261 "application/xmpp+xml", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
262 "application/json", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
263 "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
|
264 "text/plain", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
265 }; |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
266 |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
267 local supported_outputs = { |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
268 "application/xmpp+xml", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
269 "application/json", |
|
4066
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
270 "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
|
271 }; |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
272 |
| 4037 | 273 if have_cbor then |
| 274 table.insert(supported_inputs, "application/cbor"); | |
| 275 table.insert(supported_outputs, "application/cbor"); | |
| 276 end | |
| 277 | |
|
4066
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
278 -- 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
|
279 -- (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
|
280 local function flatten(t) |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
281 local form = {}; |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
282 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
|
283 if type(v) == "string" then |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
284 form[k] = v; |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
285 elseif type(v) == "number" then |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
286 form[k] = tostring(v); |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
287 elseif v == true then |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
288 form[k] = ""; |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
289 end |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
290 end |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
291 return form; |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
292 end |
|
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
293 |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
294 local function encode(type, s) |
|
4918
347e34c3c7e2
mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents:
4917
diff
changeset
|
295 if type == "text/plain" then |
|
347e34c3c7e2
mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents:
4917
diff
changeset
|
296 return s:get_child_text("body") or ""; |
|
347e34c3c7e2
mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents:
4917
diff
changeset
|
297 elseif type == "application/xmpp+xml" then |
|
347e34c3c7e2
mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents:
4917
diff
changeset
|
298 return tostring(s); |
|
347e34c3c7e2
mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents:
4917
diff
changeset
|
299 end |
|
347e34c3c7e2
mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents:
4917
diff
changeset
|
300 local mapped, err = jsonmap.st2json(s); |
|
347e34c3c7e2
mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents:
4917
diff
changeset
|
301 if not mapped then return mapped, err; end |
| 3813 | 302 if type == "application/json" then |
|
4918
347e34c3c7e2
mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents:
4917
diff
changeset
|
303 return json.encode(mapped); |
|
4066
07ae583bc565
mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents:
4037
diff
changeset
|
304 elseif type == "application/x-www-form-urlencoded" then |
|
4918
347e34c3c7e2
mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents:
4917
diff
changeset
|
305 return http.formencode(flatten(mapped)); |
| 4037 | 306 elseif type == "application/cbor" then |
|
4918
347e34c3c7e2
mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents:
4917
diff
changeset
|
307 return cbor.encode(mapped); |
| 3813 | 308 end |
|
4918
347e34c3c7e2
mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents:
4917
diff
changeset
|
309 error "unsupported encoding"; |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
310 end |
|
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
311 |
|
4478
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
312 -- GET → iq-get |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
313 local function parse_request(request, path) |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
314 if path and request.method == "GET" then |
|
4506
508cb880b163
mod_rest: Fix typos [codespell]
Kim Alvefur <zash@zash.se>
parents:
4503
diff
changeset
|
315 -- e.g. /version/{to} |
|
4503
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
316 if request.url.query then |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
317 return parse("application/x-www-form-urlencoded", request.url.query, "iq/"..path); |
|
80912726405d
mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents:
4502
diff
changeset
|
318 end |
|
4478
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
319 return parse(nil, nil, "iq/"..path); |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
320 else |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
321 return parse(request.headers.content_type, request.body, path); |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
322 end |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
323 end |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
324 |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
325 local function handle_request(event, path) |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
326 local request, response = event.request, event.response; |
|
5585
5b316088bef5
mod_rest: Use logger of HTTP request in trunk
Kim Alvefur <zash@zash.se>
parents:
5557
diff
changeset
|
327 local log = request.log or module._log; |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
328 local from; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
329 local origin; |
|
4514
81d0748bff5b
mod_rest: Add an 'echo' endpoint for debugging
Kim Alvefur <zash@zash.se>
parents:
4506
diff
changeset
|
330 local echo = path == "echo"; |
|
81d0748bff5b
mod_rest: Add an 'echo' endpoint for debugging
Kim Alvefur <zash@zash.se>
parents:
4506
diff
changeset
|
331 if echo then path = nil; end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
332 |
|
4734
e58ec4b3cf90
mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents:
4727
diff
changeset
|
333 if not request.headers.authorization and www_authenticate_header then |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
334 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
|
335 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
|
336 else |
|
5954
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
337 local err; |
|
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
338 origin, err = check_credentials(request); |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
339 if not origin then |
|
5954
9bcc26406b47
mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents:
5953
diff
changeset
|
340 return err or 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
|
341 end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
342 from = jid.join(origin.username, origin.host, origin.resource); |
|
5557
d7667d9ad96a
mod_rest: Include full_jid property on origin
Kim Alvefur <zash@zash.se>
parents:
5334
diff
changeset
|
343 origin.full_jid = from; |
|
4727
e6f46d1b3337
mod_rest: Set type on temp session to satisfy certain auth checks
Kim Alvefur <zash@zash.se>
parents:
4699
diff
changeset
|
344 origin.type = "c2s"; |
|
5585
5b316088bef5
mod_rest: Use logger of HTTP request in trunk
Kim Alvefur <zash@zash.se>
parents:
5557
diff
changeset
|
345 origin.log = log; |
|
3802
f88e07630e4e
mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents:
3801
diff
changeset
|
346 end |
|
5701
0cffeff2cd1d
mod_rest: Limit payload size (cf stanza size limits)
Kim Alvefur <zash@zash.se>
parents:
5585
diff
changeset
|
347 if type(request.body) == "string" and #request.body > stanza_size_limit then |
|
0cffeff2cd1d
mod_rest: Limit payload size (cf stanza size limits)
Kim Alvefur <zash@zash.se>
parents:
5585
diff
changeset
|
348 return post_errors.new("size", { size = #request.body; limit = stanza_size_limit }); |
|
0cffeff2cd1d
mod_rest: Limit payload size (cf stanza size limits)
Kim Alvefur <zash@zash.se>
parents:
5585
diff
changeset
|
349 end |
|
4478
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
350 local payload, err = parse_request(request, path); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
351 if not payload then |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
352 -- parse fail |
|
4036
04c11b652aeb
mod_rest: Respond to unknown payload types with HTTP status 415
Kim Alvefur <zash@zash.se>
parents:
3971
diff
changeset
|
353 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
|
354 if err == "unknown-payload-type" then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
355 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
|
356 end |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
357 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
|
358 end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
359 |
|
4841
f69c5a443156
mod_rest: Fix nested message stanzas in XEP-0297 containers
Kim Alvefur <zash@zash.se>
parents:
4745
diff
changeset
|
360 if (payload.attr.xmlns or "jabber:client") ~= "jabber:client" then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
361 return post_errors.new("xmlns"); |
|
3805
683b06c0348f
mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents:
3804
diff
changeset
|
362 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
|
363 return post_errors.new("name"); |
|
3801
d59fb4dcf100
mod_rest: Verify that @xmlns is left empty
Kim Alvefur <zash@zash.se>
parents:
3799
diff
changeset
|
364 end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
365 |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
366 local to = jid.prep(payload.attr.to); |
|
4502
48afaec5d1de
mod_rest: Allow empty @to to mean to=account is in normal XMPP
Kim Alvefur <zash@zash.se>
parents:
4488
diff
changeset
|
367 if payload.attr.to and not to then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
368 return post_errors.new("to"); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
369 end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
370 |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
371 if payload.attr.from then |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
372 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
|
373 if not requested_from then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
374 return post_errors.new("from"); |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
375 end |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
376 if jid.compare(requested_from, from) then |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
377 from = requested_from; |
|
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
378 else |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
379 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
|
380 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
381 end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
382 |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
383 payload.attr = { |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
384 from = from, |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
385 to = to, |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
386 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
|
387 type = payload.attr.type, |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
388 ["xml:lang"] = payload.attr["xml:lang"], |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
389 }; |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
390 |
|
5585
5b316088bef5
mod_rest: Use logger of HTTP request in trunk
Kim Alvefur <zash@zash.se>
parents:
5557
diff
changeset
|
391 log("debug", "Received[rest]: %s", payload:top_tag()); |
|
4478
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
392 local send_type = decide_type((request.headers.accept or "") ..",".. (request.headers.content_type or ""), supported_outputs) |
|
4514
81d0748bff5b
mod_rest: Add an 'echo' endpoint for debugging
Kim Alvefur <zash@zash.se>
parents:
4506
diff
changeset
|
393 |
|
81d0748bff5b
mod_rest: Add an 'echo' endpoint for debugging
Kim Alvefur <zash@zash.se>
parents:
4506
diff
changeset
|
394 if echo then |
|
4917
9d0ec61c70a1
mod_rest: Catch and coerce errors in echo endpoint
Kim Alvefur <zash@zash.se>
parents:
4888
diff
changeset
|
395 local ret, err = errors.coerce(encode(send_type, payload)); |
|
9d0ec61c70a1
mod_rest: Catch and coerce errors in echo endpoint
Kim Alvefur <zash@zash.se>
parents:
4888
diff
changeset
|
396 if not ret then return err; end |
|
4514
81d0748bff5b
mod_rest: Add an 'echo' endpoint for debugging
Kim Alvefur <zash@zash.se>
parents:
4506
diff
changeset
|
397 response.headers.content_type = send_type; |
|
4917
9d0ec61c70a1
mod_rest: Catch and coerce errors in echo endpoint
Kim Alvefur <zash@zash.se>
parents:
4888
diff
changeset
|
398 return ret; |
|
4514
81d0748bff5b
mod_rest: Add an 'echo' endpoint for debugging
Kim Alvefur <zash@zash.se>
parents:
4506
diff
changeset
|
399 end |
|
81d0748bff5b
mod_rest: Add an 'echo' endpoint for debugging
Kim Alvefur <zash@zash.se>
parents:
4506
diff
changeset
|
400 |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
401 if payload.name == "iq" then |
|
4699
a8af632daf48
mod_rest: Support returning multiple replies in an <xmpp> container
Kim Alvefur <zash@zash.se>
parents:
4532
diff
changeset
|
402 local responses = st.stanza("xmpp"); |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
403 function origin.send(stanza) |
|
4699
a8af632daf48
mod_rest: Support returning multiple replies in an <xmpp> container
Kim Alvefur <zash@zash.se>
parents:
4532
diff
changeset
|
404 responses:add_direct_child(stanza); |
|
3910
49efd1323a1b
mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents:
3909
diff
changeset
|
405 end |
| 4735 | 406 if compat_preevents(origin, payload) then return 202; end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
407 |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
408 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
|
409 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
|
410 elseif #payload.tags ~= 1 then |
|
4244
07c11080027e
mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents:
4242
diff
changeset
|
411 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
|
412 end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
413 |
|
4941
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
414 -- special handling of multiple responses to MAM queries primarily from |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
415 -- remote hosts, local go directly to origin.send() |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
416 local archive_event_name = "message"..event_suffix(from); |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
417 local archive_handler; |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
418 local archive_query = payload:get_child("query", "urn:xmpp:mam:2"); |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
419 if archive_query then |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
420 archive_handler = function(result_event) |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
421 if result_event.stanza:find("{urn:xmpp:mam:2}result/@queryid") == archive_query.attr.queryid then |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
422 origin.send(result_event.stanza); |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
423 return true; |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
424 end |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
425 end |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
426 module:hook(archive_event_name, archive_handler, 1); |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
427 end |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
428 |
|
5332
e0b5468aae49
mod_rest: Allow passing configuring a timeout for <iq> responses
Kim Alvefur <zash@zash.se>
parents:
5087
diff
changeset
|
429 local iq_timeout = tonumber(request.headers.prosody_rest_timeout) or module:get_option_number("rest_iq_timeout", 60*2); |
|
5334
3c51eab0afe8
mod_rest: Get correct type from config
Kim Alvefur <zash@zash.se>
parents:
5332
diff
changeset
|
430 iq_timeout = math.min(iq_timeout, module:get_option_number("rest_iq_max_timeout", 300)); |
|
5332
e0b5468aae49
mod_rest: Allow passing configuring a timeout for <iq> responses
Kim Alvefur <zash@zash.se>
parents:
5087
diff
changeset
|
431 |
|
e0b5468aae49
mod_rest: Allow passing configuring a timeout for <iq> responses
Kim Alvefur <zash@zash.se>
parents:
5087
diff
changeset
|
432 local p = module:send_iq(payload, origin, iq_timeout):next( |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
433 function (result) |
|
5585
5b316088bef5
mod_rest: Use logger of HTTP request in trunk
Kim Alvefur <zash@zash.se>
parents:
5557
diff
changeset
|
434 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
|
435 response.headers.content_type = send_type; |
|
4943
e67cc71727ca
mod_rest: Fix attempt to index nil in handling of single iq response
Kim Alvefur <zash@zash.se>
parents:
4942
diff
changeset
|
436 if responses[1] then |
|
e67cc71727ca
mod_rest: Fix attempt to index nil in handling of single iq response
Kim Alvefur <zash@zash.se>
parents:
4942
diff
changeset
|
437 local tail = responses[#responses]; |
|
e67cc71727ca
mod_rest: Fix attempt to index nil in handling of single iq response
Kim Alvefur <zash@zash.se>
parents:
4942
diff
changeset
|
438 if tail.name ~= "iq" or tail.attr.from ~= result.stanza.attr.from or tail.attr.id ~= result.stanza.attr.id then |
|
e67cc71727ca
mod_rest: Fix attempt to index nil in handling of single iq response
Kim Alvefur <zash@zash.se>
parents:
4942
diff
changeset
|
439 origin.send(result.stanza); |
|
e67cc71727ca
mod_rest: Fix attempt to index nil in handling of single iq response
Kim Alvefur <zash@zash.se>
parents:
4942
diff
changeset
|
440 end |
|
4942
83a54f4af94c
mod_rest: Ensure MAM result-iq is included in results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4941
diff
changeset
|
441 end |
|
4699
a8af632daf48
mod_rest: Support returning multiple replies in an <xmpp> container
Kim Alvefur <zash@zash.se>
parents:
4532
diff
changeset
|
442 if responses[2] then |
|
a8af632daf48
mod_rest: Support returning multiple replies in an <xmpp> container
Kim Alvefur <zash@zash.se>
parents:
4532
diff
changeset
|
443 return encode(send_type, responses); |
|
a8af632daf48
mod_rest: Support returning multiple replies in an <xmpp> container
Kim Alvefur <zash@zash.se>
parents:
4532
diff
changeset
|
444 end |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
445 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
|
446 end, |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
447 function (error) |
|
3909
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
448 if not errors.is_err(error) then |
|
5585
5b316088bef5
mod_rest: Use logger of HTTP request in trunk
Kim Alvefur <zash@zash.se>
parents:
5557
diff
changeset
|
449 log("error", "Uncaught native error: %s", error); |
|
3909
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
450 return select(2, errors.coerce(nil, error)); |
|
eb27e51cf2c9
mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents:
3887
diff
changeset
|
451 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
|
452 response.headers.content_type = send_type; |
|
5585
5b316088bef5
mod_rest: Use logger of HTTP request in trunk
Kim Alvefur <zash@zash.se>
parents:
5557
diff
changeset
|
453 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
|
454 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
|
455 else |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
456 return error; |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
457 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
458 end); |
|
4941
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
459 |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
460 if archive_handler then |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
461 p:finally(function () |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
462 module:unhook(archive_event_name, archive_handler); |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
463 end) |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
464 end |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
465 |
|
e7b9bc629ecc
mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents:
4922
diff
changeset
|
466 return p; |
|
3805
683b06c0348f
mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents:
3804
diff
changeset
|
467 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
|
468 function origin.send(stanza) |
|
5585
5b316088bef5
mod_rest: Use logger of HTTP request in trunk
Kim Alvefur <zash@zash.se>
parents:
5557
diff
changeset
|
469 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
|
470 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
|
471 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
|
472 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
|
473 end |
| 4735 | 474 if compat_preevents(origin, payload) then return 202; end |
|
4242
6a91d217acc9
mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents:
4066
diff
changeset
|
475 |
|
3814
0dede5b0ab27
mod_rest: Fix return status when sending and forgetting
Kim Alvefur <zash@zash.se>
parents:
3813
diff
changeset
|
476 module:send(payload, origin); |
|
0dede5b0ab27
mod_rest: Fix return status when sending and forgetting
Kim Alvefur <zash@zash.se>
parents:
3813
diff
changeset
|
477 return 202; |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
478 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
479 end |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
480 |
|
4888
dc7c9ae15f43
mod_rest: Ensure mod_http is loaded before API demo
Kim Alvefur <zash@zash.se>
parents:
4841
diff
changeset
|
481 module:depends("http"); |
|
dc7c9ae15f43
mod_rest: Ensure mod_http is loaded before API demo
Kim Alvefur <zash@zash.se>
parents:
4841
diff
changeset
|
482 |
|
4488
eea62d30ae08
mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents:
4481
diff
changeset
|
483 local demo_handlers = {}; |
|
eea62d30ae08
mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents:
4481
diff
changeset
|
484 if module:get_option_path("rest_demo_resources", nil) then |
|
eea62d30ae08
mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents:
4481
diff
changeset
|
485 demo_handlers = module:require"apidemo"; |
|
eea62d30ae08
mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents:
4481
diff
changeset
|
486 end |
|
eea62d30ae08
mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents:
4481
diff
changeset
|
487 |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
488 -- Handle stanzas submitted via HTTP |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
489 module:provides("http", { |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
490 route = { |
|
4478
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
491 POST = handle_request; |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
492 ["POST /*"] = handle_request; |
|
7ab0c423688a
mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents:
4477
diff
changeset
|
493 ["GET /*"] = handle_request; |
|
4488
eea62d30ae08
mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents:
4481
diff
changeset
|
494 |
|
eea62d30ae08
mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents:
4481
diff
changeset
|
495 -- Only if api_demo_resources are set |
|
eea62d30ae08
mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents:
4481
diff
changeset
|
496 ["GET /"] = demo_handlers.redirect; |
|
eea62d30ae08
mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents:
4481
diff
changeset
|
497 ["GET /demo/"] = demo_handlers.main_page; |
|
eea62d30ae08
mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents:
4481
diff
changeset
|
498 ["GET /demo/openapi.yaml"] = demo_handlers.schema; |
|
eea62d30ae08
mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents:
4481
diff
changeset
|
499 ["GET /demo/*"] = demo_handlers.resources; |
|
3794
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
500 }; |
|
4b258329e6e4
mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff
changeset
|
501 }); |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
502 |
|
5087
438fbebf74ac
mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents:
5086
diff
changeset
|
503 function new_webhook(rest_url, send_type) |
|
4920
bdac7c717c91
mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents:
4918
diff
changeset
|
504 local function get_url() return rest_url; end |
|
bdac7c717c91
mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents:
4918
diff
changeset
|
505 if rest_url:find("%b{}") then |
|
bdac7c717c91
mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents:
4918
diff
changeset
|
506 local httputil = require "util.http"; |
|
bdac7c717c91
mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents:
4918
diff
changeset
|
507 local render_url = require"util.interpolation".new("%b{}", httputil.urlencode); |
|
bdac7c717c91
mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents:
4918
diff
changeset
|
508 function get_url(stanza) |
|
bdac7c717c91
mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents:
4918
diff
changeset
|
509 local at = stanza.attr; |
|
bdac7c717c91
mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents:
4918
diff
changeset
|
510 return render_url(rest_url, { kind = stanza.name, type = at.type, to = at.to, from = at.from }); |
|
bdac7c717c91
mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents:
4918
diff
changeset
|
511 end |
|
bdac7c717c91
mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents:
4918
diff
changeset
|
512 end |
| 3813 | 513 if send_type == "json" then |
| 514 send_type = "application/json"; | |
| 515 end | |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
516 |
|
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
517 module:set_status("info", "Not yet connected"); |
|
4920
bdac7c717c91
mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents:
4918
diff
changeset
|
518 http.request(get_url(st.stanza("meta", { type = "info", to = module.host, from = module.host })), { |
|
3861
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
519 method = "OPTIONS", |
|
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
520 }, function (body, code, response) |
|
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
521 if code == 0 then |
|
4921
816b23e09c20
mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents:
4920
diff
changeset
|
522 module:log_status("error", "Could not connect to callback URL %q: %s", rest_url, body); |
|
816b23e09c20
mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents:
4920
diff
changeset
|
523 elseif code == 200 then |
|
3862
3b6b8dcff78e
mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents:
3861
diff
changeset
|
524 module:set_status("info", "Connected"); |
|
4921
816b23e09c20
mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents:
4920
diff
changeset
|
525 if response.headers.accept then |
|
816b23e09c20
mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents:
4920
diff
changeset
|
526 send_type = decide_type(response.headers.accept, supported_outputs); |
|
816b23e09c20
mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents:
4920
diff
changeset
|
527 module:log("debug", "Set 'rest_callback_content_type' = %q based on Accept header", send_type); |
|
816b23e09c20
mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents:
4920
diff
changeset
|
528 end |
|
816b23e09c20
mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents:
4920
diff
changeset
|
529 else |
|
816b23e09c20
mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents:
4920
diff
changeset
|
530 module:log_status("warn", "Unexpected response code %d from OPTIONS probe", code); |
|
816b23e09c20
mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents:
4920
diff
changeset
|
531 module:log("warn", "Endpoint said: %s", body); |
|
3861
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
532 end |
|
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
533 end); |
|
ede3d1724dd1
mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents:
3858
diff
changeset
|
534 |
|
4245
7bf3bf81c9ef
mod_rest: Use HTTP error mapping from net.http.errors
Kim Alvefur <zash@zash.se>
parents:
4244
diff
changeset
|
535 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
|
536 |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
537 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
|
538 local stanza, origin = event.stanza, event.origin; |
|
5086
dec4b2e31d1c
mod_rest: Do not allow replies to <iq type=result> from webhooks
Kim Alvefur <zash@zash.se>
parents:
5001
diff
changeset
|
539 local reply_allowed = stanza.attr.type ~= "error" and stanza.attr.type ~= "result"; |
|
4250
8b489203e4d3
mod_rest: Ensure no attempt is made to reply to an error stanza
Kim Alvefur <zash@zash.se>
parents:
4249
diff
changeset
|
540 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
|
541 local receipt; |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
542 |
|
4250
8b489203e4d3
mod_rest: Ensure no attempt is made to reply to an error stanza
Kim Alvefur <zash@zash.se>
parents:
4249
diff
changeset
|
543 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
|
544 reply_needed = true; |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
545 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
|
546 end |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
547 |
|
3812
f027b8b1e794
mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents:
3811
diff
changeset
|
548 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
|
549 |
|
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
550 -- 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
|
551 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
|
552 |
|
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
553 module:log("debug", "Sending[rest]: %s", stanza:top_tag()); |
|
4920
bdac7c717c91
mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents:
4918
diff
changeset
|
554 http.request(get_url(stanza), { |
|
3799
a1f1f703d604
mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents:
3798
diff
changeset
|
555 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
|
556 headers = { |
|
3811
eb25110696cd
mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents:
3810
diff
changeset
|
557 ["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
|
558 ["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
|
559 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
|
560 }, |
|
4247
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
561 }):next(function (response) |
|
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
562 module:set_status("info", "Connected"); |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
563 local reply; |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
564 |
|
4247
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
565 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
|
566 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
|
567 return; |
|
8b489203e4d3
mod_rest: Ensure no attempt is made to reply to an error stanza
Kim Alvefur <zash@zash.se>
parents:
4249
diff
changeset
|
568 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
|
569 if not reply_needed then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
570 -- Delivered, no reply |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
571 return; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
572 end |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
573 else |
|
3867
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
574 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
|
575 if not parsed then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
576 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
|
577 elseif parsed.name ~= stanza.name then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
578 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
|
579 else |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
580 parsed.attr = { |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
581 from = stanza.attr.to, |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
582 to = stanza.attr.from, |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
583 id = parsed.attr.id or id.medium(); |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
584 type = parsed.attr.type, |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
585 ["xml:lang"] = parsed.attr["xml:lang"], |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
586 }; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
587 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
|
588 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
|
589 end |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
590 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
|
591 parsed.attr.type = "error"; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
592 end |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
593 if parsed.attr.type == "error" then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
594 parsed.attr.id = stanza.attr.id; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
595 elseif parsed.name == "iq" then |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
596 parsed.attr.id = stanza.attr.id; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
597 parsed.attr.type = "result"; |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
598 end |
|
839224be5299
mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents:
3866
diff
changeset
|
599 reply = parsed; |
|
3821
11272a3233ce
mod_rest: Fix replying to groupchat messages
Kim Alvefur <zash@zash.se>
parents:
3816
diff
changeset
|
600 end |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
601 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
602 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
603 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
|
604 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
|
605 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
|
606 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
|
607 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
|
608 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
|
609 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
610 -- 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
|
611 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
|
612 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
|
613 elseif code_hundreds == 400 then |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
614 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
|
615 elseif code_hundreds == 500 then |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
616 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
|
617 else |
|
3810
91ff86fc3b20
mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents:
3807
diff
changeset
|
618 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
|
619 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
620 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
621 |
|
3798
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
622 if receipt then |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
623 reply:add_direct_child(receipt); |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
624 end |
|
9b4fd2553365
mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents:
3797
diff
changeset
|
625 |
|
3803
dc2b5a412286
mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents:
3802
diff
changeset
|
626 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
|
627 |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
628 origin.send(reply); |
|
4247
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
629 end, |
|
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
630 function (err) |
|
1f93fa24611d
mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents:
4245
diff
changeset
|
631 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
|
632 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
|
633 end):catch(function (err) |
|
64aa1d9d70ac
mod_rest: Catch and log errors in callback promise chain
Kim Alvefur <zash@zash.se>
parents:
4247
diff
changeset
|
634 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
|
635 end); |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
636 |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
637 return true; |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
638 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
639 |
|
5087
438fbebf74ac
mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents:
5086
diff
changeset
|
640 return handle_stanza; |
|
438fbebf74ac
mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents:
5086
diff
changeset
|
641 end |
|
438fbebf74ac
mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents:
5086
diff
changeset
|
642 |
|
438fbebf74ac
mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents:
5086
diff
changeset
|
643 -- Forward stanzas from XMPP to HTTP and return any reply |
|
438fbebf74ac
mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents:
5086
diff
changeset
|
644 local rest_url = module:get_option_string("rest_callback_url", nil); |
|
438fbebf74ac
mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents:
5086
diff
changeset
|
645 if rest_url then |
|
438fbebf74ac
mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents:
5086
diff
changeset
|
646 local send_type = module:get_option_string("rest_callback_content_type", "application/xmpp+xml"); |
|
438fbebf74ac
mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents:
5086
diff
changeset
|
647 |
|
438fbebf74ac
mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents:
5086
diff
changeset
|
648 local handle_stanza = new_webhook(rest_url, send_type); |
|
438fbebf74ac
mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents:
5086
diff
changeset
|
649 |
|
4922
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
650 local send_kinds = module:get_option_set("rest_callback_stanzas", { "message", "presence", "iq" }); |
|
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
651 |
|
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
652 local event_presets = { |
|
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
653 -- Don't override everything on normal VirtualHosts by default |
|
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
654 ["local"] = { "host" }, |
|
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
655 -- Comonents get to handle all kinds of stanzas |
|
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
656 ["component"] = { "bare", "full", "host" }, |
|
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
657 }; |
|
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
658 local hook_events = module:get_option_set("rest_callback_events", event_presets[module:get_host_type()]); |
|
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
659 for kind in send_kinds do |
|
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
660 for event in hook_events do |
|
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
661 module:hook(kind.."/"..event, handle_stanza, -1); |
|
c83b009b5bc5
mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents:
4921
diff
changeset
|
662 end |
|
3795
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
663 end |
|
f51308fcba83
mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents:
3794
diff
changeset
|
664 end |
|
3842
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3832
diff
changeset
|
665 |
|
3929
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
666 local supported_errors = { |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
667 "text/html", |
|
3931
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
668 "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
|
669 "application/json", |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
670 }; |
|
bd687d586a8a
mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents:
3926
diff
changeset
|
671 |
|
6206
ac7e2992fe6e
mod_rest: Strip down error payloads to avoid stack overflow
Kim Alvefur <zash@zash.se>
parents:
5993
diff
changeset
|
672 -- strip some stuff, notably the optional traceback table that casues stack overflow in util.json |
|
ac7e2992fe6e
mod_rest: Strip down error payloads to avoid stack overflow
Kim Alvefur <zash@zash.se>
parents:
5993
diff
changeset
|
673 local function simplify_error(e) |
|
6244
c71d8bc77c95
mod_rest: Skip unpacking error object when missing (thanks Martin)
Kim Alvefur <zash@zash.se>
parents:
6206
diff
changeset
|
674 if not e then return end |
|
6206
ac7e2992fe6e
mod_rest: Strip down error payloads to avoid stack overflow
Kim Alvefur <zash@zash.se>
parents:
5993
diff
changeset
|
675 return { |
|
ac7e2992fe6e
mod_rest: Strip down error payloads to avoid stack overflow
Kim Alvefur <zash@zash.se>
parents:
5993
diff
changeset
|
676 type = e.type; |
|
ac7e2992fe6e
mod_rest: Strip down error payloads to avoid stack overflow
Kim Alvefur <zash@zash.se>
parents:
5993
diff
changeset
|
677 condition = e.condition; |
|
ac7e2992fe6e
mod_rest: Strip down error payloads to avoid stack overflow
Kim Alvefur <zash@zash.se>
parents:
5993
diff
changeset
|
678 text = e.text; |
|
ac7e2992fe6e
mod_rest: Strip down error payloads to avoid stack overflow
Kim Alvefur <zash@zash.se>
parents:
5993
diff
changeset
|
679 extra = e.extra; |
|
ac7e2992fe6e
mod_rest: Strip down error payloads to avoid stack overflow
Kim Alvefur <zash@zash.se>
parents:
5993
diff
changeset
|
680 source = e.source; |
|
ac7e2992fe6e
mod_rest: Strip down error payloads to avoid stack overflow
Kim Alvefur <zash@zash.se>
parents:
5993
diff
changeset
|
681 }; |
|
ac7e2992fe6e
mod_rest: Strip down error payloads to avoid stack overflow
Kim Alvefur <zash@zash.se>
parents:
5993
diff
changeset
|
682 end |
|
ac7e2992fe6e
mod_rest: Strip down error payloads to avoid stack overflow
Kim Alvefur <zash@zash.se>
parents:
5993
diff
changeset
|
683 |
|
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
684 local http_server = require "net.http.server"; |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
685 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
|
686 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
|
687 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
|
688 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
|
689 if response then |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
690 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
|
691 end |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
692 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
|
693 if event.error then |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
694 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
|
695 if event.error.text then |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
696 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
|
697 end |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
698 end |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
699 return tostring(stream_error); |
|
2e8b284ac8b3
mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents:
3930
diff
changeset
|
700 elseif response_as == "application/json" then |
|
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
701 if response then |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
702 response.headers.content_type = "application/json"; |
|
3842
501c7edc8c37
mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents:
3832
diff
changeset
|
703 end |
|
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
704 return json.encode({ |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
705 type = "error", |
|
6206
ac7e2992fe6e
mod_rest: Strip down error payloads to avoid stack overflow
Kim Alvefur <zash@zash.se>
parents:
5993
diff
changeset
|
706 error = simplify_error(event.error), |
|
3873
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
707 code = event.code, |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
708 }); |
|
fea0c1bed1a0
mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents:
3872
diff
changeset
|
709 end |
|
3933
93147b89ea67
mod_rest: Avoid interfering with mod_http_oauth2 errors (fixes #1500)
Kim Alvefur <zash@zash.se>
parents:
3931
diff
changeset
|
710 end, 1); |