Software / code / prosody-modules
Annotate
mod_rest/mod_rest.lua @ 6287:5b269511ade7
mod_http_oauth2: Forbid inclusion of disabled grant and response types
Better than asserting that at least one allowed grant or response type
is included.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Tue, 03 Jun 2025 17:04:19 +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); |