comparison mod_pubsub_post/mod_pubsub_post.lua @ 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
comparison
equal deleted inserted replaced
3013:8bfba31a1f8b 3014:72dbc9b66de8
1 module:depends("http"); 1 module:depends("http");
2 2
3 local st = require "util.stanza"; 3 local st = require "util.stanza";
4 local json = require "util.json"; 4 local json = require "util.json";
5 local xml = require "util.xml";
5 local uuid_generate = require "util.uuid".generate; 6 local uuid_generate = require "util.uuid".generate;
6 local timestamp_generate = require "util.datetime".datetime; 7 local timestamp_generate = require "util.datetime".datetime;
7 8
8 local pubsub_service = module:depends("pubsub").service; 9 local pubsub_service = module:depends("pubsub").service;
9 10
11 local error_mapping = {
12 ["forbidden"] = 403;
13 ["item-not-found"] = 404;
14 ["internal-server-error"] = 500;
15 ["conflict"] = 409;
16 };
17
18 local function publish_payload(node, item_id, payload)
19 local post_item = st.stanza("item", { xmlns = "http://jabber.org/protocol/pubsub", id = item_id, })
20 :add_child(payload);
21 local ok, err = pubsub_service:publish(node, true, item_id, post_item);
22 module:log("debug", ":publish(%q, true, %q, %s) -> %q", node, item_id, payload:top_tag(), err or "");
23 if not ok then
24 return error_mapping[err] or 500;
25 end
26 return 202;
27 end
28
29 local function handle_xml(node, payload)
30 local xmlpayload, err = xml.parse(payload);
31 if not xmlpayload then
32 module:log("debug", "XML parse error: %s\n%q", err, payload);
33 return { status_code = 400, body = tostring(err) };
34 end
35 return publish_payload(node, "current", xmlpayload);
36 end
37
10 function handle_POST(event, path) 38 function handle_POST(event, path)
11 local data = event.request.body; 39 local request = event.request;
12 local item_id = "default"; 40 module:log("debug", "Handling POST: \n%s\n", tostring(request.body));
13 41
14 local post_item = st.stanza("item", { id = item_id, xmlns = "http://jabber.org/protocol/pubsub" }) 42 local content_type = request.headers.content_type or "application/octet-stream";
15 :tag("entry", { xmlns = "http://www.w3.org/2005/Atom" }) 43
16 :tag("id"):text(uuid_generate()):up() 44 if content_type == "application/xml" or content_type:sub(-4) == "+xml" then
17 :tag("title"):text(data):up() 45 return handle_xml(path, request.body);
18 :tag("author") 46 end
19 :tag("name"):text(event.request.conn:ip()):up() 47
20 :up() 48 module:log("debug", "Unsupported content-type: %q", content_type);
21 :tag("published"):text(timestamp_generate()):up(); 49 return 415;
22
23 local ok, err = pubsub_service:publish(path, true, item_id, post_item);
24 module:log("debug", "Handled POST: \n%s\n", tostring(event.request.body));
25 return ok and "Posted" or ("Error: "..err);
26 end 50 end
27 51
28 module:provides("http", { 52 module:provides("http", {
29 route = { 53 route = {
30 ["POST /*"] = handle_POST; 54 ["POST /*"] = handle_POST;