comparison mod_rest/mod_rest.lua @ 4503:80912726405d

mod_rest: Allow passing e.g. disco 'node' as a ?query variable This enables e.g. GET /disco/pubsub.example.org?node=princely_musings Note the hack to skip this for ping.
author Kim Alvefur <zash@zash.se>
date Sun, 07 Mar 2021 22:01:50 +0100
parents 48afaec5d1de
children 508cb880b163
comparison
equal deleted inserted replaced
4502:48afaec5d1de 4503:80912726405d
63 local function amend_from_path(data, path) 63 local function amend_from_path(data, path)
64 local st_kind, st_type, st_to = path:match("^([mpi]%w+)/(%w+)/(.*)$"); 64 local st_kind, st_type, st_to = path:match("^([mpi]%w+)/(%w+)/(.*)$");
65 if not st_kind then return; end 65 if not st_kind then return; end
66 if st_kind == "iq" and st_type ~= "get" and st_type ~= "set" then 66 if st_kind == "iq" and st_type ~= "get" and st_type ~= "set" then
67 -- GET /iq/disco/jid 67 -- GET /iq/disco/jid
68 data.kind = "iq"; 68 data = {
69 data.type = "get"; 69 kind = "iq";
70 data[st_type] = true; 70 type = "get";
71 [st_type] = st_type == "ping" or data or {};
72 };
71 else 73 else
72 data.kind = st_kind; 74 data.kind = st_kind;
73 data.type = st_type; 75 data.type = st_type;
74 end 76 end
75 if st_to and st_to ~= "" then 77 if st_to and st_to ~= "" then
85 elseif mimetype == "application/json" then 87 elseif mimetype == "application/json" then
86 local parsed, err = json.decode(data); 88 local parsed, err = json.decode(data);
87 if not parsed then 89 if not parsed then
88 return parsed, err; 90 return parsed, err;
89 end 91 end
90 if path and not amend_from_path(parsed, path) then return nil, "invalid-path"; end 92 if path then
93 parsed = amend_from_path(parsed, path);
94 if not parsed then return nil, "invalid-path"; end
95 end
91 return jsonmap.json2st(parsed); 96 return jsonmap.json2st(parsed);
92 elseif mimetype == "application/cbor" and have_cbor then 97 elseif mimetype == "application/cbor" and have_cbor then
93 local parsed, err = cbor.decode(data); 98 local parsed, err = cbor.decode(data);
94 if not parsed then 99 if not parsed then
95 return parsed, err; 100 return parsed, err;
96 end 101 end
97 return jsonmap.json2st(parsed); 102 return jsonmap.json2st(parsed);
98 elseif mimetype == "application/x-www-form-urlencoded"then 103 elseif mimetype == "application/x-www-form-urlencoded"then
99 local parsed = http.formdecode(data); 104 local parsed = http.formdecode(data);
100 if type(parsed) == "string" then 105 if type(parsed) == "string" then
106 -- This should reject GET /iq/query/to?messagebody
107 if path then
108 return nil, "invalid-query";
109 end
101 return parse("text/plain", parsed); 110 return parse("text/plain", parsed);
102 end 111 end
103 for i = #parsed, 1, -1 do 112 for i = #parsed, 1, -1 do
104 parsed[i] = nil; 113 parsed[i] = nil;
105 end 114 end
106 if path and not amend_from_path(parsed, path) then return nil, "invalid-path"; end 115 if path then
116 parsed = amend_from_path(parsed, path);
117 if not parsed then return nil, "invalid-path"; end
118 end
107 return jsonmap.json2st(parsed); 119 return jsonmap.json2st(parsed);
108 elseif mimetype == "text/plain" then 120 elseif mimetype == "text/plain" then
109 if not path then 121 if not path then
110 return st.message({ type = "chat" }, data); 122 return st.message({ type = "chat" }, data);
111 end 123 end
112 local parsed = {}; 124 local parsed = {};
113 if not amend_from_path(parsed, path) then return nil, "invalid-path"; end 125 if path then
126 parsed = amend_from_path(parsed, path);
127 if not parsed then return nil, "invalid-path"; end
128 end
114 if parsed.kind == "message" then 129 if parsed.kind == "message" then
115 parsed.body = data; 130 parsed.body = data;
116 elseif parsed.kind == "presence" then 131 elseif parsed.kind == "presence" then
117 parsed.show = data; 132 parsed.show = data;
118 else 133 else
201 216
202 -- GET → iq-get 217 -- GET → iq-get
203 local function parse_request(request, path) 218 local function parse_request(request, path)
204 if path and request.method == "GET" then 219 if path and request.method == "GET" then
205 -- e.g. /verison/{to} 220 -- e.g. /verison/{to}
221 if request.url.query then
222 return parse("application/x-www-form-urlencoded", request.url.query, "iq/"..path);
223 end
206 return parse(nil, nil, "iq/"..path); 224 return parse(nil, nil, "iq/"..path);
207 else 225 else
208 return parse(request.headers.content_type, request.body, path); 226 return parse(request.headers.content_type, request.body, path);
209 end 227 end
210 end 228 end