mod_pubsub_post/mod_pubsub_post.lua
author Kim Alvefur <zash@zash.se>
Sun, 20 May 2018 00:04:41 +0200
changeset 3019 338b7c808ecc
parent 3018 72dbc9b66de8
child 3020 3f4e2340bfdc
permissions -rw-r--r--
mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1623
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
module:depends("http");
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
local st = require "util.stanza";
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     4
local json = require "util.json";
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
     5
local xml = require "util.xml";
1623
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
local uuid_generate = require "util.uuid".generate;
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     7
local timestamp_generate = require "util.datetime".datetime;
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
local pubsub_service = module:depends("pubsub").service;
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    11
local error_mapping = {
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    12
	["forbidden"] = 403;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    13
	["item-not-found"] = 404;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    14
	["internal-server-error"] = 500;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    15
	["conflict"] = 409;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    16
};
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    17
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    18
local function publish_payload(node, item_id, payload)
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    19
	local post_item = st.stanza("item", { xmlns = "http://jabber.org/protocol/pubsub", id = item_id, })
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    20
		:add_child(payload);
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    21
	local ok, err = pubsub_service:publish(node, true, item_id, post_item);
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    22
	module:log("debug", ":publish(%q, true, %q, %s) -> %q", node, item_id, payload:top_tag(), err or "");
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    23
	if not ok then
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    24
		return error_mapping[err] or 500;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    25
	end
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    26
	return 202;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    27
end
1623
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
3019
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    29
local function publish_atom(node, feed)
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    30
	for entry in feed:childtags("entry") do
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    31
		local item_id = entry:get_child_text("id");
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    32
		if not item_id then
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    33
			item_id = uuid_generate();
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    34
			entry:tag("id"):text(item_id):up();
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    35
		end
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    36
		if not entry:get_child_text("published") then
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    37
			entry:tag("published"):text(timestamp_generate()):up();
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    38
		end
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    39
		local resp = publish_payload(node, item_id, entry);
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    40
		if resp ~= 202 then return resp; end
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    41
	end
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    42
	return 202;
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    43
end
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    44
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    45
local function handle_xml(node, payload)
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    46
	local xmlpayload, err = xml.parse(payload);
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    47
	if not xmlpayload then
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    48
		module:log("debug", "XML parse error: %s\n%q", err, payload);
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    49
		return { status_code = 400, body = tostring(err) };
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    50
	end
3019
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    51
	if xmlpayload.attr.xmlns == "http://www.w3.org/2005/Atom" and xmlpayload.name == "feed" then
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    52
		return publish_atom(node, xmlpayload);
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    53
	else
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    54
		return publish_payload(node, "current", xmlpayload);
338b7c808ecc mod_pubsub_post: Add support for posting Atom feeds, publishing each entry
Kim Alvefur <zash@zash.se>
parents: 3018
diff changeset
    55
	end
3018
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    56
end
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    57
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    58
function handle_POST(event, path)
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    59
	local request = event.request;
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    60
	module:log("debug", "Handling POST: \n%s\n", tostring(request.body));
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    61
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    62
	local content_type = request.headers.content_type or "application/octet-stream";
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    63
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    64
	if content_type == "application/xml" or content_type:sub(-4) == "+xml" then
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    65
		return handle_xml(path, request.body);
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    66
	end
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    67
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    68
	module:log("debug", "Unsupported content-type: %q", content_type);
72dbc9b66de8 mod_pubsub_post: Change to support arbitrary XML payloads
Kim Alvefur <zash@zash.se>
parents: 3017
diff changeset
    69
	return 415;
1623
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    70
end
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    71
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    72
module:provides("http", {
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    73
	route = {
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    74
		["POST /*"] = handle_POST;
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    75
	};
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    76
});
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    77
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    78
function module.load()
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    79
	module:log("debug", "Loaded at %s", module:http_url());
43c54a27bab2 mod_pubsub_post: Module to publish to pubsub nodes from a simple HTTP POST
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    80
end