diff mod_post_msg/mod_post_msg.lua @ 231:b78009874ce5

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 "="
author Kim Alvefur <zash@zash.se>
date Sat, 31 Jul 2010 18:33:56 +0200
parents ac5289d5ac8c
children 8d4f3cd41f82
line wrap: on
line diff
--- a/mod_post_msg/mod_post_msg.lua	Sat Jul 31 14:42:27 2010 +0500
+++ b/mod_post_msg/mod_post_msg.lua	Sat Jul 31 18:33:56 2010 +0200
@@ -13,6 +13,16 @@
 local test_password = require "core.usermanager".test_password;
 local b64_decode = require "util.encodings".base64.decode;
 local urldecode = require "net.http".urldecode;
+local urlparams = --require "net.http".getQueryParams or whatever MattJ names it
+function(s)
+	if not s:match("=") then return urldecode(s); end
+	local r = {}
+	s:gsub("([^=&]*)=([^&]*)", function(k,v)
+		r[ urldecode(k) ] = urldecode(v);
+		return nil
+	end)
+	return r
+end;
 
 local function http_response(code, message, extra_headers)
 	local response = {
@@ -23,7 +33,9 @@
 end
 
 local function handle_request(method, body, request)
-	if request.method ~= "POST" then return http_response(405, "Method Not Allowed"); end
+	if request.method == "BREW" then return http_response(418, "I'm a teapot"); end
+	if request.method ~= "POST" then
+		return http_response(405, "Method Not Allowed", {["Allow"] = "POST"}); end
 
 	-- message to?
 	local path_jid = request.url.path:match("[^/]+$");
@@ -43,7 +55,7 @@
 			{["WWW-Authenticate"]='Basic realm="WallyWorld"'})
 	end
 	local from_jid, password = b64_decode(request.headers.authorization
-			:gmatch("[^ ]*$")() or ""):gmatch("([^:]*):(.*)")();
+			:match("[^ ]*$") or ""):match("([^:]*):(.*)");
 	from_jid = jid_prep(from_jid)
 	if not from_jid or not password then return http_response(400, "Bad Request"); end
 	local from_user, from_host = jid_split(from_jid)
@@ -52,11 +64,44 @@
 	-- auth
 	module:log("debug", "testing authz %s", from_jid)
 	if not test_password(from_user, from_host, password) then
-		return http_response(401, "Unauthorized"); end
+		return http_response(401, "Unauthorized")
+	end
+
+	-- parse body
+	local message = {}
+	local body_type = request.headers["content-type"]
+	if body_type == "text/plain" then
+		message = {["body"] = body}
+	elseif body_type == "application/x-www-form-urlencoded" then
+		message = urlparams(body)
+		if type(message) == "string" then
+			message = {["body"] = message}
+		end
+	else
+		return http_response(415, "Unsupported Media Type")
+	end
 
+	-- guess type if not set
+	if not message["type"] then
+		if message["body"] then 
+			if message["subject"] then
+				message["type"] = "normal"
+			else
+				message["type"] = "chat"
+			end
+		elseif not message["body"] and message["subject"] then
+			message["type"] = "headline"
+		end
+	end
+
+	-- build stanza
+	local stanza = msg({["to"]=to_jid, ["from"]=from_jid, ["type"]=message["type"]})
+	if message["body"] then stanza:tag("body"):text(message["body"]):up(); end
+	if message["subject"] then stanza:tag("subject"):text(message["subject"]):up(); end
+
+	-- and finaly post it
 	module:log("debug", "message for %s", to_jid)
-	core_post_stanza(hosts[module.host], msg({to=to_jid, from=from_jid, type="chat"})
-			:tag("body"):text(body))
+	core_post_stanza(hosts[module.host], stanza)
 	return http_response(202, "Accepted")
 end