diff mod_rest/mod_rest.lua @ 4478:7ab0c423688a

mod_rest: Support GET for certain IQ queries Example: GET /rest/version/example.com 200 OK { version: { name: "thing", version: "1.0.0" } }
author Kim Alvefur <zash@zash.se>
date Sun, 28 Feb 2021 19:33:09 +0100
parents 8df6cc648963
children dad0367d33e8
line wrap: on
line diff
--- a/mod_rest/mod_rest.lua	Sun Feb 28 19:25:45 2021 +0100
+++ b/mod_rest/mod_rest.lua	Sun Feb 28 19:33:09 2021 +0100
@@ -63,8 +63,17 @@
 local function amend_from_path(data, path)
 	local st_kind, st_type, st_to = path:match("^([mpi]%w+)/(%w+)/(.*)$");
 	if not st_kind then return; end
-	data.kind = st_kind;
-	data.type = st_type;
+	if st_kind == "iq" and st_type ~= "get" and st_type ~= "set" then
+		-- GET /iq/disco/jid
+		data = {
+			kind = "iq";
+			type = "get";
+			[st_type] = data;
+		}
+	else
+		data.kind = st_kind;
+		data.type = st_type;
+	end
 	if st_to and st_to ~= "" then
 		data.to = st_to;
 	end
@@ -112,6 +121,10 @@
 			return nil, "invalid-path";
 		end
 		return jsonmap.json2st(parsed);
+	elseif not mimetype and path then
+		local parsed = amend_from_path({}, path);
+		if not parsed then return nil, "invalid-path"; end
+		return jsonmap.json2st(parsed);
 	end
 	return nil, "unknown-payload-type";
 end
@@ -188,7 +201,17 @@
 	mediatype = { code = 415, condition = "bad-format", text = "Unsupported media type" },
 });
 
-local function handle_post(event, path)
+-- GET → iq-get
+local function parse_request(request, path)
+	if path and request.method == "GET" then
+		-- e.g. /verison/{to}
+		return parse(nil, nil, "iq/"..path);
+	else
+		return parse(request.headers.content_type, request.body, path);
+	end
+end
+
+local function handle_request(event, path)
 	local request, response = event.request, event.response;
 	local from;
 	local origin;
@@ -203,7 +226,7 @@
 		end
 		from = jid.join(origin.username, origin.host, origin.resource);
 	end
-	local payload, err = parse(request.headers.content_type, request.body, path);
+	local payload, err = parse_request(request, path);
 	if not payload then
 		-- parse fail
 		local ctx = { error = err, type = request.headers.content_type, data = request.body, };
@@ -245,7 +268,7 @@
 	};
 
 	module:log("debug", "Received[rest]: %s", payload:top_tag());
-	local send_type = decide_type((request.headers.accept or "") ..",".. request.headers.content_type, supported_outputs)
+	local send_type = decide_type((request.headers.accept or "") ..",".. (request.headers.content_type or ""), supported_outputs)
 	if payload.name == "iq" then
 		function origin.send(stanza)
 			module:send(stanza);
@@ -292,8 +315,9 @@
 module:depends("http");
 module:provides("http", {
 		route = {
-			POST = handle_post;
-			["POST /*"] = handle_post;
+			POST = handle_request;
+			["POST /*"] = handle_request;
+			["GET /*"] = handle_request;
 		};
 	});