Mercurial > prosody-modules
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 229:5689ffaf97df | 231:b78009874ce5 |
|---|---|
| 11 local jid_prep = require "util.jid".prep; | 11 local jid_prep = require "util.jid".prep; |
| 12 local msg = require "util.stanza".message; | 12 local msg = require "util.stanza".message; |
| 13 local test_password = require "core.usermanager".test_password; | 13 local test_password = require "core.usermanager".test_password; |
| 14 local b64_decode = require "util.encodings".base64.decode; | 14 local b64_decode = require "util.encodings".base64.decode; |
| 15 local urldecode = require "net.http".urldecode; | 15 local urldecode = require "net.http".urldecode; |
| 16 local urlparams = --require "net.http".getQueryParams or whatever MattJ names it | |
| 17 function(s) | |
| 18 if not s:match("=") then return urldecode(s); end | |
| 19 local r = {} | |
| 20 s:gsub("([^=&]*)=([^&]*)", function(k,v) | |
| 21 r[ urldecode(k) ] = urldecode(v); | |
| 22 return nil | |
| 23 end) | |
| 24 return r | |
| 25 end; | |
| 16 | 26 |
| 17 local function http_response(code, message, extra_headers) | 27 local function http_response(code, message, extra_headers) |
| 18 local response = { | 28 local response = { |
| 19 status = code .. " " .. message; | 29 status = code .. " " .. message; |
| 20 body = message .. "\n"; } | 30 body = message .. "\n"; } |
| 21 if extra_headers then response.headers = extra_headers; end | 31 if extra_headers then response.headers = extra_headers; end |
| 22 return response | 32 return response |
| 23 end | 33 end |
| 24 | 34 |
| 25 local function handle_request(method, body, request) | 35 local function handle_request(method, body, request) |
| 26 if request.method ~= "POST" then return http_response(405, "Method Not Allowed"); end | 36 if request.method == "BREW" then return http_response(418, "I'm a teapot"); end |
| 37 if request.method ~= "POST" then | |
| 38 return http_response(405, "Method Not Allowed", {["Allow"] = "POST"}); end | |
| 27 | 39 |
| 28 -- message to? | 40 -- message to? |
| 29 local path_jid = request.url.path:match("[^/]+$"); | 41 local path_jid = request.url.path:match("[^/]+$"); |
| 30 if not path_jid or not body then return http_response(400, "Bad Request"); end | 42 if not path_jid or not body then return http_response(400, "Bad Request"); end |
| 31 local to_user, to_host = jid_split(urldecode(path_jid)); | 43 local to_user, to_host = jid_split(urldecode(path_jid)); |
| 41 if not request.headers["authorization"] then | 53 if not request.headers["authorization"] then |
| 42 return http_response(401, "Unauthorized", | 54 return http_response(401, "Unauthorized", |
| 43 {["WWW-Authenticate"]='Basic realm="WallyWorld"'}) | 55 {["WWW-Authenticate"]='Basic realm="WallyWorld"'}) |
| 44 end | 56 end |
| 45 local from_jid, password = b64_decode(request.headers.authorization | 57 local from_jid, password = b64_decode(request.headers.authorization |
| 46 :gmatch("[^ ]*$")() or ""):gmatch("([^:]*):(.*)")(); | 58 :match("[^ ]*$") or ""):match("([^:]*):(.*)"); |
| 47 from_jid = jid_prep(from_jid) | 59 from_jid = jid_prep(from_jid) |
| 48 if not from_jid or not password then return http_response(400, "Bad Request"); end | 60 if not from_jid or not password then return http_response(400, "Bad Request"); end |
| 49 local from_user, from_host = jid_split(from_jid) | 61 local from_user, from_host = jid_split(from_jid) |
| 50 if not hosts[from_host] then return http_response(401, "Unauthorized"); end | 62 if not hosts[from_host] then return http_response(401, "Unauthorized"); end |
| 51 | 63 |
| 52 -- auth | 64 -- auth |
| 53 module:log("debug", "testing authz %s", from_jid) | 65 module:log("debug", "testing authz %s", from_jid) |
| 54 if not test_password(from_user, from_host, password) then | 66 if not test_password(from_user, from_host, password) then |
| 55 return http_response(401, "Unauthorized"); end | 67 return http_response(401, "Unauthorized") |
| 68 end | |
| 56 | 69 |
| 70 -- parse body | |
| 71 local message = {} | |
| 72 local body_type = request.headers["content-type"] | |
| 73 if body_type == "text/plain" then | |
| 74 message = {["body"] = body} | |
| 75 elseif body_type == "application/x-www-form-urlencoded" then | |
| 76 message = urlparams(body) | |
| 77 if type(message) == "string" then | |
| 78 message = {["body"] = message} | |
| 79 end | |
| 80 else | |
| 81 return http_response(415, "Unsupported Media Type") | |
| 82 end | |
| 83 | |
| 84 -- guess type if not set | |
| 85 if not message["type"] then | |
| 86 if message["body"] then | |
| 87 if message["subject"] then | |
| 88 message["type"] = "normal" | |
| 89 else | |
| 90 message["type"] = "chat" | |
| 91 end | |
| 92 elseif not message["body"] and message["subject"] then | |
| 93 message["type"] = "headline" | |
| 94 end | |
| 95 end | |
| 96 | |
| 97 -- build stanza | |
| 98 local stanza = msg({["to"]=to_jid, ["from"]=from_jid, ["type"]=message["type"]}) | |
| 99 if message["body"] then stanza:tag("body"):text(message["body"]):up(); end | |
| 100 if message["subject"] then stanza:tag("subject"):text(message["subject"]):up(); end | |
| 101 | |
| 102 -- and finaly post it | |
| 57 module:log("debug", "message for %s", to_jid) | 103 module:log("debug", "message for %s", to_jid) |
| 58 core_post_stanza(hosts[module.host], msg({to=to_jid, from=from_jid, type="chat"}) | 104 core_post_stanza(hosts[module.host], stanza) |
| 59 :tag("body"):text(body)) | |
| 60 return http_response(202, "Accepted") | 105 return http_response(202, "Accepted") |
| 61 end | 106 end |
| 62 | 107 |
| 63 local ports = config.get(module.host, "core", "post_msg_ports") or { 5280 }; | 108 local ports = config.get(module.host, "core", "post_msg_ports") or { 5280 }; |
| 64 require "net.httpserver".new_from_config(ports, "msg", handle_request); | 109 require "net.httpserver".new_from_config(ports, "msg", handle_request); |
