mod_post_msg/mod_post_msg.lua
author Kim Alvefur <zash@zash.se>
Sat, 31 Jul 2010 18:33:56 +0200
changeset 231 b78009874ce5
parent 216 ac5289d5ac8c
child 320 8d4f3cd41f82
permissions -rw-r--r--
mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded Falls back to old "tread everything as body" if Content-Type says text, or lack of "="
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
216
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
-- Recive a HTTP POST and relay it
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
-- By Kim Alvefur <zash@zash.se>
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
-- Some code borrowed from mod_webpresence
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     4
--
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
-- Example usage:
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
--     curl http://example.com:5280/msg/user -u me@example.com:mypassword -d "Hello there"
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
-- This would send a message to user@example.com from me@example.com
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
local jid_split = require "util.jid".split;
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
local jid_prep = require "util.jid".prep;
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
local msg = require "util.stanza".message;
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    13
local test_password = require "core.usermanager".test_password;
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
local b64_decode = require "util.encodings".base64.decode;
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
local urldecode = require "net.http".urldecode;
231
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    16
local urlparams = --require "net.http".getQueryParams or whatever MattJ names it
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    17
function(s)
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    18
	if not s:match("=") then return urldecode(s); end
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    19
	local r = {}
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    20
	s:gsub("([^=&]*)=([^&]*)", function(k,v)
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    21
		r[ urldecode(k) ] = urldecode(v);
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    22
		return nil
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    23
	end)
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    24
	return r
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    25
end;
216
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
local function http_response(code, message, extra_headers)
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
	local response = {
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
		status = code .. " " .. message;
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
		body = message .. "\n"; }
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
	if extra_headers then response.headers = extra_headers; end
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
	return response
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    33
end
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
local function handle_request(method, body, request)
231
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    36
	if request.method == "BREW" then return http_response(418, "I'm a teapot"); end
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    37
	if request.method ~= "POST" then
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    38
		return http_response(405, "Method Not Allowed", {["Allow"] = "POST"}); end
216
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
	-- message to?
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
	local path_jid = request.url.path:match("[^/]+$");
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
	if not path_jid or not body then return http_response(400, "Bad Request"); end
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
	local to_user, to_host = jid_split(urldecode(path_jid));
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
	if to_host and not to_user and request.headers.host then
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
		to_user, to_host = to_host, request.headers.host;
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    46
		if to_host then to_host = to_host:gsub(":%d+$", ""); end
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
	end
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
	if not to_host or not to_user then return http_response(400, "Bad Request"); end 
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
	local to_jid = jid_prep(to_user .. "@" .. to_host)
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
	if not to_jid then return http_response(400, "Bad Request"); end 
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    51
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
	-- message from?
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    53
	if not request.headers["authorization"] then
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    54
		return http_response(401, "Unauthorized",
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
			{["WWW-Authenticate"]='Basic realm="WallyWorld"'})
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    56
	end
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
	local from_jid, password = b64_decode(request.headers.authorization
231
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    58
			:match("[^ ]*$") or ""):match("([^:]*):(.*)");
216
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    59
	from_jid = jid_prep(from_jid)
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    60
	if not from_jid or not password then return http_response(400, "Bad Request"); end
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
	local from_user, from_host = jid_split(from_jid)
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
	if not hosts[from_host] then return http_response(401, "Unauthorized"); end
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    63
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    64
	-- auth
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    65
	module:log("debug", "testing authz %s", from_jid)
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    66
	if not test_password(from_user, from_host, password) then
231
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    67
		return http_response(401, "Unauthorized")
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    68
	end
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    69
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    70
	-- parse body
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    71
	local message = {}
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    72
	local body_type = request.headers["content-type"]
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    73
	if body_type == "text/plain" then
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    74
		message = {["body"] = body}
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    75
	elseif body_type == "application/x-www-form-urlencoded" then
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    76
		message = urlparams(body)
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    77
		if type(message) == "string" then
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    78
			message = {["body"] = message}
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    79
		end
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    80
	else
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    81
		return http_response(415, "Unsupported Media Type")
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    82
	end
216
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
231
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    84
	-- guess type if not set
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    85
	if not message["type"] then
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    86
		if message["body"] then 
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    87
			if message["subject"] then
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    88
				message["type"] = "normal"
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    89
			else
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    90
				message["type"] = "chat"
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    91
			end
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    92
		elseif not message["body"] and message["subject"] then
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    93
			message["type"] = "headline"
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    94
		end
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    95
	end
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    96
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    97
	-- build stanza
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    98
	local stanza = msg({["to"]=to_jid, ["from"]=from_jid, ["type"]=message["type"]})
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
    99
	if message["body"] then stanza:tag("body"):text(message["body"]):up(); end
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
   100
	if message["subject"] then stanza:tag("subject"):text(message["subject"]):up(); end
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
   101
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
   102
	-- and finaly post it
216
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   103
	module:log("debug", "message for %s", to_jid)
231
b78009874ce5 mod_post_msg: add support for type, subject and body in application/x-www-form-urlencoded
Kim Alvefur <zash@zash.se>
parents: 216
diff changeset
   104
	core_post_stanza(hosts[module.host], stanza)
216
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   105
	return http_response(202, "Accepted")
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
end
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   107
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   108
local ports = config.get(module.host, "core", "post_msg_ports") or { 5280 };
ac5289d5ac8c mod_post_msg: A plugin that recives a single message by HTTP POST and relays it.
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
require "net.httpserver".new_from_config(ports, "msg", handle_request);