annotate mod_rest/mod_rest.lua @ 5929:c094eabdb30f

mod_ping_muc: Describe the client facing protocol (from XEP-0045)
author Kim Alvefur <zash@zash.se>
date Thu, 11 Jul 2024 15:14:33 +0200
parents 9bcc26406b47
children d5e6617e47cc
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 --
4921
bdac7c717c91 mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents: 4919
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
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
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
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
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
5678
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
3910
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
26 local auth_mechanisms = module:get_option_set("rest_auth_mechanisms", { "Basic", "Bearer" });
3802
f88e07630e4e mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents: 3801
diff changeset
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
5926
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
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: 5925
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: 5925
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: 5925
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: 5925
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: 5925
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: 5925
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: 5925
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: 5925
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: 5925
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: 5925
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: 5925
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: 5925
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: 5925
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: 5925
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: 5925
diff changeset
52 });
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
53
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
54 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
55 local auth_type, auth_data = string.match(request.headers.authorization, "^(%S+)%s(.+)$");
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
56 if not (auth_type and auth_data) or not auth_mechanisms:contains(auth_type) then
5926
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
57 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
58 end
3876
75b330d4fa6f mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents: 3874
diff changeset
59
3910
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
60 if auth_type == "Basic" then
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
61 local creds = base64.decode(auth_data);
5926
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
62 if not creds then
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
63 return nil, post_errors.new("malformauthz", { request = request });
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
64 end
3876
75b330d4fa6f mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents: 3874
diff changeset
65 local username, password = string.match(creds, "^([^:]+):(.*)$");
5926
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
66 if not username then
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
67 return nil, post_errors.new("malformauthz", { request = request });
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
68 end
3876
75b330d4fa6f mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents: 3874
diff changeset
69 username, password = encodings.stringprep.nodeprep(username), encodings.stringprep.saslprep(password);
5926
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
70 if not username or not password then
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
71 return false, post_errors.new("prepauthz", { request = request });
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
72 end
3876
75b330d4fa6f mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents: 3874
diff changeset
73 if not um.test_password(username, module.host, password) then
5926
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
74 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
75 end
5926
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
76 return { username = username; host = module.host };
3910
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
77 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
78 if tokens.get_token_session then
cb19cb1c03d6 mod_rest: Update for mod_tokenauth API changes (backwards-compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4988
diff changeset
79 return tokens.get_token_session(auth_data);
cb19cb1c03d6 mod_rest: Update for mod_tokenauth API changes (backwards-compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4988
diff changeset
80 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
81 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
82 if not token_info or not token_info.session then
5926
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
83 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
84 end
cb19cb1c03d6 mod_rest: Update for mod_tokenauth API changes (backwards-compatible)
Matthew Wild <mwild1@gmail.com>
parents: 4988
diff changeset
85 return token_info.session;
3910
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
86 end
3876
75b330d4fa6f mod_rest: Add support for HTTP Basic username and password authentication
Kim Alvefur <zash@zash.se>
parents: 3874
diff changeset
87 end
5926
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
88 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
89 end
3794
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
90
4734
e58ec4b3cf90 mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents: 4727
diff changeset
91 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
92 www_authenticate_header = nil;
e58ec4b3cf90 mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents: 4727
diff changeset
93 function check_credentials(request) -- luacheck: ignore 212/request
e58ec4b3cf90 mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents: 4727
diff changeset
94 return {
e58ec4b3cf90 mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents: 4727
diff changeset
95 username = id.medium():lower();
e58ec4b3cf90 mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents: 4727
diff changeset
96 host = module.host;
e58ec4b3cf90 mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents: 4727
diff changeset
97 }
e58ec4b3cf90 mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents: 4727
diff changeset
98 end
e58ec4b3cf90 mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents: 4727
diff changeset
99 end
e58ec4b3cf90 mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents: 4727
diff changeset
100
4942
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
101 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: 4923
diff changeset
102 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: 4923
diff changeset
103 if node then
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
104 if resource then
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
105 return '/full';
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
106 else
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
107 return '/bare';
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
108 end
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
109 else
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
110 return '/host';
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
111 end
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
112 end
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
113
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
114
4735
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
115 -- TODO This ought to be handled some way other than duplicating this
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
116 -- core.stanza_router code here.
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
117 local function compat_preevents(origin, stanza) --> boolean : handled
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
118 local to = stanza.attr.to;
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
119 local node, host, resource = jid.split(to);
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
120
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
121 local to_type, to_self;
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
122 if node then
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
123 if resource then
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
124 to_type = '/full';
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
125 else
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
126 to_type = '/bare';
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
127 if node == origin.username and host == origin.host then
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
128 stanza.attr.to = nil;
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
129 to_self = true;
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
130 end
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
131 end
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
132 else
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
133 if host then
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
134 to_type = '/host';
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
135 else
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
136 to_type = '/bare';
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
137 to_self = true;
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
138 end
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
139 end
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
140
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
141 local event_data = { origin = origin; stanza = stanza; to_self = to_self };
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
142
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
143 local result = module:fire_event("pre-stanza", event_data);
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
144 if result ~= nil then return true end
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
145 if module:fire_event('pre-' .. stanza.name .. to_type, event_data) then return true; end -- do preprocessing
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
146 return false
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
147 end
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
148
4477
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
149 -- (table, string) -> table
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
150 local function amend_from_path(data, path)
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
151 local st_kind, st_type, st_to = path:match("^([mpi]%w+)/(%w+)/(.*)$");
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
152 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
153 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
154 -- 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
155 data = {
80912726405d mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents: 4502
diff changeset
156 kind = "iq";
80912726405d mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents: 4502
diff changeset
157 [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
158 };
4478
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
159 else
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
160 data.kind = st_kind;
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
161 data.type = st_type;
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
162 end
4477
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
163 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
164 data.to = st_to;
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
165 end
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
166 return data;
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
167 end
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
168
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
169 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
170 mimetype = mimetype and mimetype:match("^[^; ]*");
3810
91ff86fc3b20 mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents: 3807
diff changeset
171 if mimetype == "application/xmpp+xml" then
91ff86fc3b20 mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents: 3807
diff changeset
172 return xml.parse(data);
3813
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
173 elseif mimetype == "application/json" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
174 local parsed, err = json.decode(data);
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
175 if not parsed then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
176 return parsed, err;
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
177 end
4503
80912726405d mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents: 4502
diff changeset
178 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
179 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
180 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
181 end
3813
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
182 return jsonmap.json2st(parsed);
4037
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
183 elseif mimetype == "application/cbor" and have_cbor then
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
184 local parsed, err = cbor.decode(data);
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
185 if not parsed then
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
186 return parsed, err;
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
187 end
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
188 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
189 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
190 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
191 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
192 -- 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
193 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
194 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
195 end
3911
064c32a5be7c mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents: 3910
diff changeset
196 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
197 end
064c32a5be7c mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents: 3910
diff changeset
198 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
199 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
200 end
4503
80912726405d mod_rest: Allow passing e.g. disco 'node' as a ?query variable
Kim Alvefur <zash@zash.se>
parents: 4502
diff changeset
201 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
202 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
203 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
204 end
3911
064c32a5be7c mod_rest: Support urlencoded form data (does a subset of JSON mapping)
Kim Alvefur <zash@zash.se>
parents: 3910
diff changeset
205 return jsonmap.json2st(parsed);
3810
91ff86fc3b20 mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents: 3807
diff changeset
206 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
207 if not path then
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
208 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
209 end
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
210 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
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 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
213 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
214 end
4477
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
215 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
216 parsed.body = data;
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
217 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
218 parsed.show = data;
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
219 else
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
220 return nil, "invalid-path";
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
221 end
8df6cc648963 mod_rest: Add more REST-looking way to send stanzas
Kim Alvefur <zash@zash.se>
parents: 4250
diff changeset
222 return jsonmap.json2st(parsed);
4478
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
223 elseif not mimetype and path then
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
224 local parsed = amend_from_path({}, path);
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
225 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
226 return jsonmap.json2st(parsed);
3810
91ff86fc3b20 mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents: 3807
diff changeset
227 end
91ff86fc3b20 mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents: 3807
diff changeset
228 return nil, "unknown-payload-type";
91ff86fc3b20 mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents: 3807
diff changeset
229 end
91ff86fc3b20 mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents: 3807
diff changeset
230
3929
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
231 local function decide_type(accept, supported_types)
3813
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
232 -- assumes the accept header is sorted
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
233 local ret = supported_types[1];
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
234 for i = 2, #supported_types do
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
235 if (accept:find(supported_types[i], 1, true) or 1000) < (accept:find(ret, 1, true) or 1000) then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
236 ret = supported_types[i];
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
237 end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
238 end
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
239 return ret;
3811
eb25110696cd mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents: 3810
diff changeset
240 end
eb25110696cd mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents: 3810
diff changeset
241
3929
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
242 local supported_inputs = {
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
243 "application/xmpp+xml",
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
244 "application/json",
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
245 "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
246 "text/plain",
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
247 };
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
248
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
249 local supported_outputs = {
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
250 "application/xmpp+xml",
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
251 "application/json",
4066
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
252 "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
253 };
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
254
4037
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
255 if have_cbor then
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
256 table.insert(supported_inputs, "application/cbor");
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
257 table.insert(supported_outputs, "application/cbor");
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
258 end
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
259
4066
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
260 -- 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
261 -- (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
262 local function flatten(t)
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
263 local form = {};
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
264 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
265 if type(v) == "string" then
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
266 form[k] = v;
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
267 elseif type(v) == "number" then
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
268 form[k] = tostring(v);
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
269 elseif v == true then
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
270 form[k] = "";
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
271 end
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
272 end
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
273 return form;
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
274 end
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
275
3812
f027b8b1e794 mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents: 3811
diff changeset
276 local function encode(type, s)
4919
347e34c3c7e2 mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents: 4918
diff changeset
277 if type == "text/plain" then
347e34c3c7e2 mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents: 4918
diff changeset
278 return s:get_child_text("body") or "";
347e34c3c7e2 mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents: 4918
diff changeset
279 elseif type == "application/xmpp+xml" then
347e34c3c7e2 mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents: 4918
diff changeset
280 return tostring(s);
347e34c3c7e2 mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents: 4918
diff changeset
281 end
347e34c3c7e2 mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents: 4918
diff changeset
282 local mapped, err = jsonmap.st2json(s);
347e34c3c7e2 mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents: 4918
diff changeset
283 if not mapped then return mapped, err; end
3813
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
284 if type == "application/json" then
4919
347e34c3c7e2 mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents: 4918
diff changeset
285 return json.encode(mapped);
4066
07ae583bc565 mod_rest: Add support for form-encoded output
Kim Alvefur <zash@zash.se>
parents: 4037
diff changeset
286 elseif type == "application/x-www-form-urlencoded" then
4919
347e34c3c7e2 mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents: 4918
diff changeset
287 return http.formencode(flatten(mapped));
4037
991090cb5d18 mod_rest: Add support for CBOR
Kim Alvefur <zash@zash.se>
parents: 4036
diff changeset
288 elseif type == "application/cbor" then
4919
347e34c3c7e2 mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents: 4918
diff changeset
289 return cbor.encode(mapped);
3813
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
290 end
4919
347e34c3c7e2 mod_rest: Improve error handling during format mapping
Kim Alvefur <zash@zash.se>
parents: 4918
diff changeset
291 error "unsupported encoding";
3812
f027b8b1e794 mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents: 3811
diff changeset
292 end
f027b8b1e794 mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents: 3811
diff changeset
293
4478
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
294 -- GET → iq-get
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
295 local function parse_request(request, path)
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
296 if path and request.method == "GET" then
4506
508cb880b163 mod_rest: Fix typos [codespell]
Kim Alvefur <zash@zash.se>
parents: 4503
diff changeset
297 -- 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
298 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
299 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
300 end
4478
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
301 return parse(nil, nil, "iq/"..path);
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
302 else
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
303 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
304 end
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
305 end
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
306
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
307 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
308 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
309 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
310 local from;
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
311 local origin;
4514
81d0748bff5b mod_rest: Add an 'echo' endpoint for debugging
Kim Alvefur <zash@zash.se>
parents: 4506
diff changeset
312 local echo = path == "echo";
81d0748bff5b mod_rest: Add an 'echo' endpoint for debugging
Kim Alvefur <zash@zash.se>
parents: 4506
diff changeset
313 if echo then path = nil; end
3910
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
314
4734
e58ec4b3cf90 mod_rest: Add an anonymous mode
Kim Alvefur <zash@zash.se>
parents: 4727
diff changeset
315 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
316 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
317 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
318 else
5926
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
319 local err;
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
320 origin, err = check_credentials(request);
3910
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
321 if not origin then
5926
9bcc26406b47 mod_rest: Return specific errors from credential checks
Kim Alvefur <zash@zash.se>
parents: 5925
diff changeset
322 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
323 end
3910
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
324 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
325 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
326 origin.type = "c2s";
5585
5b316088bef5 mod_rest: Use logger of HTTP request in trunk
Kim Alvefur <zash@zash.se>
parents: 5557
diff changeset
327 origin.log = log;
3802
f88e07630e4e mod_rest: Add support for simple Bearer token auth
Kim Alvefur <zash@zash.se>
parents: 3801
diff changeset
328 end
5678
0cffeff2cd1d mod_rest: Limit payload size (cf stanza size limits)
Kim Alvefur <zash@zash.se>
parents: 5585
diff changeset
329 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
330 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
331 end
4478
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
332 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
333 if not payload then
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
334 -- parse fail
4036
04c11b652aeb mod_rest: Respond to unknown payload types with HTTP status 415
Kim Alvefur <zash@zash.se>
parents: 3971
diff changeset
335 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
336 if err == "unknown-payload-type" then
4244
07c11080027e mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents: 4242
diff changeset
337 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
338 end
4244
07c11080027e mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents: 4242
diff changeset
339 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
340 end
4242
6a91d217acc9 mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents: 4066
diff changeset
341
4841
f69c5a443156 mod_rest: Fix nested message stanzas in XEP-0297 containers
Kim Alvefur <zash@zash.se>
parents: 4745
diff changeset
342 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
343 return post_errors.new("xmlns");
3805
683b06c0348f mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents: 3804
diff changeset
344 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
345 return post_errors.new("name");
3801
d59fb4dcf100 mod_rest: Verify that @xmlns is left empty
Kim Alvefur <zash@zash.se>
parents: 3799
diff changeset
346 end
4242
6a91d217acc9 mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents: 4066
diff changeset
347
3794
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
348 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
349 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
350 return post_errors.new("to");
3794
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
351 end
4242
6a91d217acc9 mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents: 4066
diff changeset
352
3910
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
353 if payload.attr.from then
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
354 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
355 if not requested_from then
4244
07c11080027e mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents: 4242
diff changeset
356 return post_errors.new("from");
3794
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
357 end
3910
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
358 if jid.compare(requested_from, from) then
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
359 from = requested_from;
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
360 else
4244
07c11080027e mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents: 4242
diff changeset
361 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
362 end
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
363 end
4242
6a91d217acc9 mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents: 4066
diff changeset
364
3794
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
365 payload.attr = {
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
366 from = from,
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
367 to = to,
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
368 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
369 type = payload.attr.type,
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
370 ["xml:lang"] = payload.attr["xml:lang"],
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
371 };
4242
6a91d217acc9 mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents: 4066
diff changeset
372
5585
5b316088bef5 mod_rest: Use logger of HTTP request in trunk
Kim Alvefur <zash@zash.se>
parents: 5557
diff changeset
373 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
374 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
375
81d0748bff5b mod_rest: Add an 'echo' endpoint for debugging
Kim Alvefur <zash@zash.se>
parents: 4506
diff changeset
376 if echo then
4918
9d0ec61c70a1 mod_rest: Catch and coerce errors in echo endpoint
Kim Alvefur <zash@zash.se>
parents: 4888
diff changeset
377 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
378 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
379 response.headers.content_type = send_type;
4918
9d0ec61c70a1 mod_rest: Catch and coerce errors in echo endpoint
Kim Alvefur <zash@zash.se>
parents: 4888
diff changeset
380 return ret;
4514
81d0748bff5b mod_rest: Add an 'echo' endpoint for debugging
Kim Alvefur <zash@zash.se>
parents: 4506
diff changeset
381 end
81d0748bff5b mod_rest: Add an 'echo' endpoint for debugging
Kim Alvefur <zash@zash.se>
parents: 4506
diff changeset
382
3794
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
383 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
384 local responses = st.stanza("xmpp");
3910
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
385 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
386 responses:add_direct_child(stanza);
3910
49efd1323a1b mod_rest: Add support for token authentication
Matthew Wild <mwild1@gmail.com>
parents: 3909
diff changeset
387 end
4735
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
388 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
389
3794
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
390 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
391 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
392 elseif #payload.tags ~= 1 then
4244
07c11080027e mod_rest: Use util.error registry datatype
Kim Alvefur <zash@zash.se>
parents: 4242
diff changeset
393 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
394 end
4242
6a91d217acc9 mod_rest: Add whitespace to improve readability, code navigation
Kim Alvefur <zash@zash.se>
parents: 4066
diff changeset
395
4942
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
396 -- 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: 4923
diff changeset
397 -- 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: 4923
diff changeset
398 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: 4923
diff changeset
399 local archive_handler;
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
400 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: 4923
diff changeset
401 if archive_query then
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
402 archive_handler = function(result_event)
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
403 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: 4923
diff changeset
404 origin.send(result_event.stanza);
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
405 return true;
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
406 end
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
407 end
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
408 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: 4923
diff changeset
409 end
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
410
5332
e0b5468aae49 mod_rest: Allow passing configuring a timeout for <iq> responses
Kim Alvefur <zash@zash.se>
parents: 5087
diff changeset
411 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
412 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
413
e0b5468aae49 mod_rest: Allow passing configuring a timeout for <iq> responses
Kim Alvefur <zash@zash.se>
parents: 5087
diff changeset
414 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
415 function (result)
5585
5b316088bef5 mod_rest: Use logger of HTTP request in trunk
Kim Alvefur <zash@zash.se>
parents: 5557
diff changeset
416 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
417 response.headers.content_type = send_type;
4944
e67cc71727ca mod_rest: Fix attempt to index nil in handling of single iq response
Kim Alvefur <zash@zash.se>
parents: 4943
diff changeset
418 if responses[1] then
e67cc71727ca mod_rest: Fix attempt to index nil in handling of single iq response
Kim Alvefur <zash@zash.se>
parents: 4943
diff changeset
419 local tail = responses[#responses];
e67cc71727ca mod_rest: Fix attempt to index nil in handling of single iq response
Kim Alvefur <zash@zash.se>
parents: 4943
diff changeset
420 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: 4943
diff changeset
421 origin.send(result.stanza);
e67cc71727ca mod_rest: Fix attempt to index nil in handling of single iq response
Kim Alvefur <zash@zash.se>
parents: 4943
diff changeset
422 end
4943
83a54f4af94c mod_rest: Ensure MAM result-iq is included in results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4942
diff changeset
423 end
4699
a8af632daf48 mod_rest: Support returning multiple replies in an <xmpp> container
Kim Alvefur <zash@zash.se>
parents: 4532
diff changeset
424 if responses[2] then
a8af632daf48 mod_rest: Support returning multiple replies in an <xmpp> container
Kim Alvefur <zash@zash.se>
parents: 4532
diff changeset
425 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
426 end
3812
f027b8b1e794 mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents: 3811
diff changeset
427 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
428 end,
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
429 function (error)
3909
eb27e51cf2c9 mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents: 3887
diff changeset
430 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
431 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
432 return select(2, errors.coerce(nil, error));
eb27e51cf2c9 mod_rest: Handle uncaught native errors correctly
Matthew Wild <mwild1@gmail.com>
parents: 3887
diff changeset
433 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
434 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
435 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
436 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
437 else
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
438 return error;
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
439 end
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
440 end);
4942
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
441
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
442 if archive_handler then
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
443 p:finally(function ()
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
444 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: 4923
diff changeset
445 end)
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
446 end
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
447
e7b9bc629ecc mod_rest: Add special handling to catch MAM results from remote hosts
Kim Alvefur <zash@zash.se>
parents: 4923
diff changeset
448 return p;
3805
683b06c0348f mod_rest: Validate stanza kind earlier
Kim Alvefur <zash@zash.se>
parents: 3804
diff changeset
449 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
450 function origin.send(stanza)
5585
5b316088bef5 mod_rest: Use logger of HTTP request in trunk
Kim Alvefur <zash@zash.se>
parents: 5557
diff changeset
451 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
452 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
453 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
454 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
455 end
4735
58a20d5ac6e9 mod_rest: Fire pre-events
Kim Alvefur <zash@zash.se>
parents: 4734
diff changeset
456 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
457
3814
0dede5b0ab27 mod_rest: Fix return status when sending and forgetting
Kim Alvefur <zash@zash.se>
parents: 3813
diff changeset
458 module:send(payload, origin);
0dede5b0ab27 mod_rest: Fix return status when sending and forgetting
Kim Alvefur <zash@zash.se>
parents: 3813
diff changeset
459 return 202;
3794
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
460 end
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
461 end
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
462
4888
dc7c9ae15f43 mod_rest: Ensure mod_http is loaded before API demo
Kim Alvefur <zash@zash.se>
parents: 4841
diff changeset
463 module:depends("http");
dc7c9ae15f43 mod_rest: Ensure mod_http is loaded before API demo
Kim Alvefur <zash@zash.se>
parents: 4841
diff changeset
464
4488
eea62d30ae08 mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents: 4481
diff changeset
465 local demo_handlers = {};
eea62d30ae08 mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents: 4481
diff changeset
466 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
467 demo_handlers = module:require"apidemo";
eea62d30ae08 mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents: 4481
diff changeset
468 end
eea62d30ae08 mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents: 4481
diff changeset
469
3794
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
470 -- Handle stanzas submitted via HTTP
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
471 module:provides("http", {
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
472 route = {
4478
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
473 POST = handle_request;
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
474 ["POST /*"] = handle_request;
7ab0c423688a mod_rest: Support GET for certain IQ queries
Kim Alvefur <zash@zash.se>
parents: 4477
diff changeset
475 ["GET /*"] = handle_request;
4488
eea62d30ae08 mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents: 4481
diff changeset
476
eea62d30ae08 mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents: 4481
diff changeset
477 -- 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
478 ["GET /"] = demo_handlers.redirect;
eea62d30ae08 mod_rest: Add option for serving interactive openapi documentation
Kim Alvefur <zash@zash.se>
parents: 4481
diff changeset
479 ["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
480 ["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
481 ["GET /demo/*"] = demo_handlers.resources;
3794
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
482 };
4b258329e6e4 mod_rest: Initial commit of another RESTful API module
Kim Alvefur <zash@zash.se>
parents:
diff changeset
483 });
3795
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
484
5087
438fbebf74ac mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents: 5086
diff changeset
485 function new_webhook(rest_url, send_type)
4921
bdac7c717c91 mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents: 4919
diff changeset
486 local function get_url() return rest_url; end
bdac7c717c91 mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents: 4919
diff changeset
487 if rest_url:find("%b{}") then
bdac7c717c91 mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents: 4919
diff changeset
488 local httputil = require "util.http";
bdac7c717c91 mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents: 4919
diff changeset
489 local render_url = require"util.interpolation".new("%b{}", httputil.urlencode);
bdac7c717c91 mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents: 4919
diff changeset
490 function get_url(stanza)
bdac7c717c91 mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents: 4919
diff changeset
491 local at = stanza.attr;
bdac7c717c91 mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents: 4919
diff changeset
492 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: 4919
diff changeset
493 end
bdac7c717c91 mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents: 4919
diff changeset
494 end
3813
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
495 if send_type == "json" then
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
496 send_type = "application/json";
aa1ad69c7c10 mod_rest: Add JSON support
Kim Alvefur <zash@zash.se>
parents: 3812
diff changeset
497 end
3795
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
498
3862
3b6b8dcff78e mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents: 3861
diff changeset
499 module:set_status("info", "Not yet connected");
4921
bdac7c717c91 mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents: 4919
diff changeset
500 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
501 method = "OPTIONS",
ede3d1724dd1 mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents: 3858
diff changeset
502 }, function (body, code, response)
3862
3b6b8dcff78e mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents: 3861
diff changeset
503 if code == 0 then
4922
816b23e09c20 mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents: 4921
diff changeset
504 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: 4921
diff changeset
505 elseif code == 200 then
3862
3b6b8dcff78e mod_rest: Log connectivity problems via module status API
Kim Alvefur <zash@zash.se>
parents: 3861
diff changeset
506 module:set_status("info", "Connected");
4922
816b23e09c20 mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents: 4921
diff changeset
507 if response.headers.accept then
816b23e09c20 mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents: 4921
diff changeset
508 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: 4921
diff changeset
509 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: 4921
diff changeset
510 end
816b23e09c20 mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents: 4921
diff changeset
511 else
816b23e09c20 mod_rest: Improve logging of results from callback startup probe
Kim Alvefur <zash@zash.se>
parents: 4921
diff changeset
512 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: 4921
diff changeset
513 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
514 end
ede3d1724dd1 mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents: 3858
diff changeset
515 end);
ede3d1724dd1 mod_rest: Attempt to auto-discover data type wanted by callback
Kim Alvefur <zash@zash.se>
parents: 3858
diff changeset
516
4245
7bf3bf81c9ef mod_rest: Use HTTP error mapping from net.http.errors
Kim Alvefur <zash@zash.se>
parents: 4244
diff changeset
517 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
518
3795
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
519 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
520 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
521 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
522 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
523 local receipt;
9b4fd2553365 mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
524
4250
8b489203e4d3 mod_rest: Ensure no attempt is made to reply to an error stanza
Kim Alvefur <zash@zash.se>
parents: 4249
diff changeset
525 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
526 reply_needed = true;
9b4fd2553365 mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
527 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
528 end
3795
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
529
3812
f027b8b1e794 mod_rest: Factor out serialization of outgoing stanzas
Kim Alvefur <zash@zash.se>
parents: 3811
diff changeset
530 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
531
a1f1f703d604 mod_rest: Allow collection of original stanza after sending HTTP request
Kim Alvefur <zash@zash.se>
parents: 3798
diff changeset
532 -- 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
533 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
534
3803
dc2b5a412286 mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents: 3802
diff changeset
535 module:log("debug", "Sending[rest]: %s", stanza:top_tag());
4921
bdac7c717c91 mod_rest: Support parameters in callback URL
Kim Alvefur <zash@zash.se>
parents: 4919
diff changeset
536 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
537 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
538 headers = {
3811
eb25110696cd mod_rest: Factor out response content type selection
Kim Alvefur <zash@zash.se>
parents: 3810
diff changeset
539 ["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
540 ["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
541 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
542 },
4247
1f93fa24611d mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents: 4245
diff changeset
543 }):next(function (response)
1f93fa24611d mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents: 4245
diff changeset
544 module:set_status("info", "Connected");
3810
91ff86fc3b20 mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents: 3807
diff changeset
545 local reply;
3795
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
546
4247
1f93fa24611d mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents: 4245
diff changeset
547 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
548 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
549 return;
8b489203e4d3 mod_rest: Ensure no attempt is made to reply to an error stanza
Kim Alvefur <zash@zash.se>
parents: 4249
diff changeset
550 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
551 if not reply_needed then
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
552 -- Delivered, no reply
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
553 return;
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
554 end
3810
91ff86fc3b20 mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents: 3807
diff changeset
555 else
3867
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
556 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
557 if not parsed then
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
558 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
559 elseif parsed.name ~= stanza.name then
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
560 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
561 else
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
562 parsed.attr = {
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
563 from = stanza.attr.to,
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
564 to = stanza.attr.from,
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
565 id = parsed.attr.id or id.medium();
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
566 type = parsed.attr.type,
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
567 ["xml:lang"] = parsed.attr["xml:lang"],
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
568 };
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
569 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
570 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
571 end
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
572 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
573 parsed.attr.type = "error";
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
574 end
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
575 if parsed.attr.type == "error" then
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
576 parsed.attr.id = stanza.attr.id;
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
577 elseif parsed.name == "iq" then
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
578 parsed.attr.id = stanza.attr.id;
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
579 parsed.attr.type = "result";
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
580 end
839224be5299 mod_rest: Skip attempting parse empty response
Kim Alvefur <zash@zash.se>
parents: 3866
diff changeset
581 reply = parsed;
3821
11272a3233ce mod_rest: Fix replying to groupchat messages
Kim Alvefur <zash@zash.se>
parents: 3816
diff changeset
582 end
3795
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
583 end
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
584
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
585 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
586 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
587 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
588 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
589 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
590 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
591 end
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
592 -- 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
593 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
594 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
595 elseif code_hundreds == 400 then
3810
91ff86fc3b20 mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents: 3807
diff changeset
596 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
597 elseif code_hundreds == 500 then
3810
91ff86fc3b20 mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents: 3807
diff changeset
598 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
599 else
3810
91ff86fc3b20 mod_rest: Factor out payload parsing
Kim Alvefur <zash@zash.se>
parents: 3807
diff changeset
600 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
601 end
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
602 end
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
603
3798
9b4fd2553365 mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
604 if receipt then
9b4fd2553365 mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
605 reply:add_direct_child(receipt);
9b4fd2553365 mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
606 end
9b4fd2553365 mod_rest: Handle receipt requests on message stanzas
Kim Alvefur <zash@zash.se>
parents: 3797
diff changeset
607
3803
dc2b5a412286 mod_rest: Log sent and received stanzas in style of mod_c2s etc
Kim Alvefur <zash@zash.se>
parents: 3802
diff changeset
608 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
609
3795
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
610 origin.send(reply);
4247
1f93fa24611d mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents: 4245
diff changeset
611 end,
1f93fa24611d mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents: 4245
diff changeset
612 function (err)
1f93fa24611d mod_rest: Use promise based HTTP client API
Kim Alvefur <zash@zash.se>
parents: 4245
diff changeset
613 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
614 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
615 end):catch(function (err)
64aa1d9d70ac mod_rest: Catch and log errors in callback promise chain
Kim Alvefur <zash@zash.se>
parents: 4247
diff changeset
616 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
617 end);
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
618
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
619 return true;
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
5087
438fbebf74ac mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents: 5086
diff changeset
622 return handle_stanza;
438fbebf74ac mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents: 5086
diff changeset
623 end
438fbebf74ac mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents: 5086
diff changeset
624
438fbebf74ac mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents: 5086
diff changeset
625 -- 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
626 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
627 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
628 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
629
438fbebf74ac mod_rest: Wrap webhook setup in a function for future reuse
Kim Alvefur <zash@zash.se>
parents: 5086
diff changeset
630 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
631
4923
c83b009b5bc5 mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents: 4922
diff changeset
632 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: 4922
diff changeset
633
c83b009b5bc5 mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents: 4922
diff changeset
634 local event_presets = {
c83b009b5bc5 mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents: 4922
diff changeset
635 -- 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: 4922
diff changeset
636 ["local"] = { "host" },
c83b009b5bc5 mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents: 4922
diff changeset
637 -- 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: 4922
diff changeset
638 ["component"] = { "bare", "full", "host" },
c83b009b5bc5 mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents: 4922
diff changeset
639 };
c83b009b5bc5 mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents: 4922
diff changeset
640 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: 4922
diff changeset
641 for kind in send_kinds do
c83b009b5bc5 mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents: 4922
diff changeset
642 for event in hook_events do
c83b009b5bc5 mod_rest: Add configuration of which stanzas to route to callback
Kim Alvefur <zash@zash.se>
parents: 4922
diff changeset
643 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: 4922
diff changeset
644 end
3795
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
645 end
f51308fcba83 mod_rest: Allow specifying a webhook/callback to handle incoming stanzas
Kim Alvefur <zash@zash.se>
parents: 3794
diff changeset
646 end
3842
501c7edc8c37 mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents: 3832
diff changeset
647
3929
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
648 local supported_errors = {
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
649 "text/html",
3931
2e8b284ac8b3 mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents: 3930
diff changeset
650 "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
651 "application/json",
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
652 };
bd687d586a8a mod_rest: Separate lists of mediatypes for input, output and errors
Kim Alvefur <zash@zash.se>
parents: 3926
diff changeset
653
3873
fea0c1bed1a0 mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents: 3872
diff changeset
654 local http_server = require "net.http.server";
fea0c1bed1a0 mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents: 3872
diff changeset
655 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
656 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
657 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
658 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
659 if response then
2e8b284ac8b3 mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents: 3930
diff changeset
660 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
661 end
2e8b284ac8b3 mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents: 3930
diff changeset
662 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
663 if event.error then
2e8b284ac8b3 mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents: 3930
diff changeset
664 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
665 if event.error.text then
2e8b284ac8b3 mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents: 3930
diff changeset
666 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
667 end
2e8b284ac8b3 mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents: 3930
diff changeset
668 end
2e8b284ac8b3 mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents: 3930
diff changeset
669 return tostring(stream_error);
2e8b284ac8b3 mod_rest: Add an XML error formatter (fixes #1499)
Kim Alvefur <zash@zash.se>
parents: 3930
diff changeset
670 elseif response_as == "application/json" then
3873
fea0c1bed1a0 mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents: 3872
diff changeset
671 if response then
fea0c1bed1a0 mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents: 3872
diff changeset
672 response.headers.content_type = "application/json";
3842
501c7edc8c37 mod_rest: Encode errors as JSON
Kim Alvefur <zash@zash.se>
parents: 3832
diff changeset
673 end
3873
fea0c1bed1a0 mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents: 3872
diff changeset
674 return json.encode({
fea0c1bed1a0 mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents: 3872
diff changeset
675 type = "error",
fea0c1bed1a0 mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents: 3872
diff changeset
676 error = event.error,
fea0c1bed1a0 mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents: 3872
diff changeset
677 code = event.code,
fea0c1bed1a0 mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents: 3872
diff changeset
678 });
fea0c1bed1a0 mod_rest: Back out 513a8a7fab41
Kim Alvefur <zash@zash.se>
parents: 3872
diff changeset
679 end
3933
93147b89ea67 mod_rest: Avoid interfering with mod_http_oauth2 errors (fixes #1500)
Kim Alvefur <zash@zash.se>
parents: 3931
diff changeset
680 end, 1);