mod_http: Revamp module for new API and config

This commit is contained in:
Matthew Wild 2012-04-23 14:16:59 +01:00
parent 1e7d11c689
commit 46e69d7017

View file

@ -1,6 +1,6 @@
-- Prosody IM
-- Copyright (C) 2008-2010 Matthew Wild
-- Copyright (C) 2008-2010 Waqas Hussain
-- Copyright (C) 2008-2012 Matthew Wild
-- Copyright (C) 2008-2012 Waqas Hussain
--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
@ -8,67 +8,68 @@
module:set_global();
--local sessions = module:shared("sessions");
local parse_url = require "socket.url".parse;
local server = require "net.http.server";
--[[function listener.associate_session(conn, session)
sessions[conn] = session;
end]]
local function normalize_path(path)
if path:sub(1,1) ~= "/" then path = "/"..path; end
if path:sub(-1,-1) == "/" then path = path:sub(1, -2); end
return path;
end
local NULL = {};
local handlers = {};
local function get_http_event(http_module, app_name, key)
local method, path = key:match("^(%S+)%s+(.+)$");
if not method and key:sub(1,1) == "/" then
method, path = "GET", key;
else
return nil;
end
path = normalize_path(path);
local app_path = normalize_path(http_module:get_option_string(app_name.."_http_path", "/"..app_name));
return method:upper().." "..http_module.host..app_path..path;
end
function build_handlers(host)
if not hosts[host] then return; end
local h = {};
handlers[host] = h;
for mod_name, module in pairs(modulemanager.get_modules(host)) do
module = module.module;
if module.items then
for _, item in ipairs(module.items["http-handler"] or NULL) do
local previous = handlers[item.path];
if not previous and item.path then
h[item.path] = item;
function module.add_host(module)
local apps = {};
module.environment.apps = apps;
local function http_app_added(event)
local app_name = event.item.name;
if not app_name then
-- TODO: Link to docs
module:log("error", "HTTP app has no 'name', add one or use module:provides('http', app)");
return;
end
apps[app_name] = apps[app_name] or {};
local app_handlers = apps[app_name];
for key, handler in pairs(event.item.route or {}) do
local event_name = get_http_event(module, app_name, key);
if event_name then
if not app_handlers[event_name] then
app_handlers[event_name] = handler;
server.add_handler(event_name, handler);
else
module:log("warn", "App %s added handler twice for '%s', ignoring", app_name, event_name);
end
else
module:log("error", "Invalid route in %s: %q", app_name, key);
end
end
end
return h;
end
function clear_handlers(event)
handlers[event.source.host] = nil;
end
function get_handler(host, path)
local h = handlers[host] or build_handlers(host);
if h then
local item = h[path];
return item and item.handler;
local function http_app_removed(event)
local app_handlers = apps[event.item.name];
apps[event.item.name] = nil;
for event, handler in pairs(app_handlers) do
server.remove_handler(event, handler);
end
end
module:handle_items("http-provider", http_app_added, http_app_removed);
end
module:handle_items("http-handler", clear_handlers, clear_handlers, false);
function http_handler(event)
local request, response = event.request, event.response;
local handler = get_handler(request.headers.host:match("[^:]*"):lower(), request.path:match("[^?]*"));
if handler then
handler(request, response);
return true;
end
end
local server = require "net.http.server";
local listener = server.listener;
server.add_handler("*", http_handler);
function module.unload()
server.remove_handler("*", http_handler);
end
--require "net.http.server".listen_on(8080);
module:add_item("net-provider", {
name = "http";
listener = listener;
listener = server.listener;
default_port = 5280;
multiplex = {
pattern = "^[A-Z]";
@ -77,7 +78,8 @@ module:add_item("net-provider", {
module:add_item("net-provider", {
name = "https";
listener = listener;
listener = server.listener;
default_port = 5281;
encryption = "ssl";
multiplex = {
pattern = "^[A-Z]";