changeset 3014:72dbc9b66de8

mod_pubsub_post: Change to support arbitrary XML payloads
author Kim Alvefur <zash@zash.se>
date Sat, 19 May 2018 23:56:39 +0200
parents 8bfba31a1f8b
children 338b7c808ecc
files mod_pubsub_post/mod_pubsub_post.lua
diffstat 1 files changed, 39 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/mod_pubsub_post/mod_pubsub_post.lua	Sat May 19 23:54:05 2018 +0200
+++ b/mod_pubsub_post/mod_pubsub_post.lua	Sat May 19 23:56:39 2018 +0200
@@ -2,27 +2,51 @@
 
 local st = require "util.stanza";
 local json = require "util.json";
+local xml = require "util.xml";
 local uuid_generate = require "util.uuid".generate;
 local timestamp_generate = require "util.datetime".datetime;
 
 local pubsub_service = module:depends("pubsub").service;
 
-function handle_POST(event, path)
-	local data = event.request.body;
-	local item_id = "default";
+local error_mapping = {
+	["forbidden"] = 403;
+	["item-not-found"] = 404;
+	["internal-server-error"] = 500;
+	["conflict"] = 409;
+};
+
+local function publish_payload(node, item_id, payload)
+	local post_item = st.stanza("item", { xmlns = "http://jabber.org/protocol/pubsub", id = item_id, })
+		:add_child(payload);
+	local ok, err = pubsub_service:publish(node, true, item_id, post_item);
+	module:log("debug", ":publish(%q, true, %q, %s) -> %q", node, item_id, payload:top_tag(), err or "");
+	if not ok then
+		return error_mapping[err] or 500;
+	end
+	return 202;
+end
 
-	local post_item = st.stanza("item", { id = item_id, xmlns = "http://jabber.org/protocol/pubsub" })
-		:tag("entry", { xmlns = "http://www.w3.org/2005/Atom" })
-			:tag("id"):text(uuid_generate()):up()
-			:tag("title"):text(data):up()
-			:tag("author")
-				:tag("name"):text(event.request.conn:ip()):up()
-				:up()
-			:tag("published"):text(timestamp_generate()):up();
-	
-	local ok, err = pubsub_service:publish(path, true, item_id, post_item);
-	module:log("debug", "Handled POST: \n%s\n", tostring(event.request.body));
-	return ok and "Posted" or ("Error: "..err);
+local function handle_xml(node, payload)
+	local xmlpayload, err = xml.parse(payload);
+	if not xmlpayload then
+		module:log("debug", "XML parse error: %s\n%q", err, payload);
+		return { status_code = 400, body = tostring(err) };
+	end
+	return publish_payload(node, "current", xmlpayload);
+end
+
+function handle_POST(event, path)
+	local request = event.request;
+	module:log("debug", "Handling POST: \n%s\n", tostring(request.body));
+
+	local content_type = request.headers.content_type or "application/octet-stream";
+
+	if content_type == "application/xml" or content_type:sub(-4) == "+xml" then
+		return handle_xml(path, request.body);
+	end
+
+	module:log("debug", "Unsupported content-type: %q", content_type);
+	return 415;
 end
 
 module:provides("http", {