# HG changeset patch # User Kim Alvefur # Date 1526766999 -7200 # Node ID 72dbc9b66de8e72553981661bb9205be9e490435 # Parent 8bfba31a1f8b5ca901caf97d9b5a5bc845a77d1f mod_pubsub_post: Change to support arbitrary XML payloads diff -r 8bfba31a1f8b -r 72dbc9b66de8 mod_pubsub_post/mod_pubsub_post.lua --- 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", {