Created
January 18, 2011 15:52
-
-
Save zeen/784623 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Recive a HTTP POST and relay it | |
-- Author: Waqas Hussain | |
-- Derived from mod_post_msg by Kim Alvefur <[email protected]> | |
-- Some code borrowed from mod_webpresence | |
-- | |
-- Example usage: | |
-- curl http://example.com:5280/presence/user -d "Hello there" | |
-- or | |
-- curl http://example.com:5280/presence/[email protected] -d "Hello there" | |
-- This would set presence of [email protected] with status 'Hello there' | |
-- another example: | |
-- curl http://example.com:5280/presence/[email protected] -d "status=Something&show=away&priority=20" | |
local jid_split = require "util.jid".split; | |
local jid_prep = require "util.jid".prep; | |
local msg = require "util.stanza".message; | |
local st = require "util.stanza"; | |
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 = { | |
status = code .. " " .. message; | |
body = message .. "\n"; } | |
if extra_headers then response.headers = extra_headers; end | |
return response | |
end | |
local function handle_request(method, body, request) | |
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("[^/]+$"); | |
if not path_jid or not body then return http_response(400, "Bad Request"); end | |
local to_user, to_host = jid_split(urldecode(path_jid)); | |
if to_host and not to_user and request.headers.host then | |
to_user, to_host = to_host, request.headers.host; | |
if to_host then to_host = to_host:gsub(":%d+$", ""); end | |
end | |
if not to_host or not to_user then return http_response(400, "Bad Request"); end | |
local to_jid = jid_prep(to_user .. "@" .. to_host) | |
if not to_jid then return http_response(400, "Bad Request"); end | |
--[[-- message from? | |
if not request.headers["authorization"] then | |
return http_response(401, "Unauthorized", | |
{["WWW-Authenticate"]='Basic realm="WallyWorld"'}) | |
end | |
local from_jid, password = b64_decode(request.headers.authorization | |
: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) | |
if not hosts[from_host] then return http_response(401, "Unauthorized"); end | |
-- 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]] | |
-- parse body | |
local message = {} | |
local body_type = request.headers["content-type"] | |
if body_type == "text/plain" then | |
message = {["status"] = body} | |
elseif body_type == "application/x-www-form-urlencoded" then | |
message = urlparams(body) | |
if type(message) == "string" then | |
message = {["status"] = 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 = st.presence(); | |
if message["status"] then stanza:tag("status"):text(message["status"]):up(); end | |
if message["show"] then stanza:tag("show"):text(message["show"]):up(); end | |
if message["priority"] then stanza:tag("priority"):text(message["priority"]):up(); end | |
-- and finaly post it | |
--module:log("debug", "message for %s", to_jid) | |
for full_jid, session in pairs(bare_sessions[to_jid] and bare_sessions[to_jid].sessions or {}) do | |
stanza.attr.from = full_jid; | |
core_post_stanza(session, stanza) | |
end | |
return http_response(202, "Accepted") | |
end | |
local ports = require "core.configmanager".get(module.host, "core", "set_presence_rest_ports") or { 5280 }; | |
require "net.httpserver".new_from_config(ports, "presence", handle_request); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment