aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2012-04-27 23:11:23 +0100
committerMatthew Wild <mwild1@gmail.com>2012-04-27 23:11:23 +0100
commitfb9c619707409485b4b1afbd5585785759c6922d (patch)
tree490a1c1038ac91d4f0b047faf54f9ea77980196f
parent987c79e4d0cbf7c35a6201603813a3a0ff491db2 (diff)
downloadprosody-fb9c619707409485b4b1afbd5585785759c6922d.tar.gz
prosody-fb9c619707409485b4b1afbd5585785759c6922d.zip
net.http.server, mod_http: Support http_default_host config option to specify where to direct requests for unknown HTTP vhosts
-rw-r--r--net/http/server.lua97
-rw-r--r--plugins/mod_http.lua7
2 files changed, 63 insertions, 41 deletions
diff --git a/net/http/server.lua b/net/http/server.lua
index 978a5a82..325eb42f 100644
--- a/net/http/server.lua
+++ b/net/http/server.lua
@@ -18,8 +18,9 @@ local legacy_httpserver = require "net.httpserver";
local _M = {};
local sessions = {};
-
local listener = {};
+local hosts = {};
+local default_host;
local function is_wildcard_event(event)
return event:sub(-2, -1) == "/*";
@@ -169,54 +170,59 @@ function handle_request(conn, request, finish_cb)
};
conn._http_open_response = response;
- local err;
- if not request.headers.host then
- err = "No 'Host' header";
+ local host = (request.headers.host or ""):match("[^:]+");
+
+ -- Some sanity checking
+ local err_code, err;
+ if not host then
+ err_code, err = 400, "Missing or invalid 'Host' header";
elseif not request.path then
- err = "Invalid path";
+ err_code, err = 400, "Invalid path";
+ end
+ if not hosts[host] then
+ if hosts[default_host] then
+ host = default_host;
+ else
+ err_code, err = 404, "Unknown host: "..host;
+ end
end
if err then
- response.status_code = 400;
- response.headers.content_type = "text/html";
- response:send(events.fire_event("http-error", { code = 400, message = err }));
- else
- local host = request.headers.host;
- if host then
- host = host:match("[^:]*"):lower();
- local event = request.method.." "..host..request.path:match("[^?]*");
- local payload = { request = request, response = response };
- --log("debug", "Firing event: %s", event);
- local result = events.fire_event(event, payload);
- if result ~= nil then
- if result ~= true then
- local code, body = 200, "";
- local result_type = type(result);
- if result_type == "number" then
- response.status_code = result;
- if result >= 400 then
- body = events.fire_event("http-error", { code = result });
- end
- elseif result_type == "string" then
- body = result;
- elseif result_type == "table" then
- body = result.body;
- result.body = nil;
- for k, v in pairs(result) do
- response[k] = v;
- end
- end
- response:send(body);
+ response.status_code = err_code;
+ response:send(events.fire_event("http-error", { code = err_code, message = err }));
+ return;
+ end
+
+ local event = request.method.." "..host..request.path:match("[^?]*");
+ local payload = { request = request, response = response };
+ --log("debug", "Firing event: %s", event);
+ local result = events.fire_event(event, payload);
+ if result ~= nil then
+ if result ~= true then
+ local code, body = 200, "";
+ local result_type = type(result);
+ if result_type == "number" then
+ response.status_code = result;
+ if result >= 400 then
+ body = events.fire_event("http-error", { code = result });
+ end
+ elseif result_type == "string" then
+ body = result;
+ elseif result_type == "table" then
+ body = result.body;
+ result.body = nil;
+ for k, v in pairs(result) do
+ response[k] = v;
end
- return;
end
+ response:send(body);
end
-
- -- if handler not called, return 404
- response.status_code = 404;
- response.headers.content_type = "text/html";
- response:send(events.fire_event("http-error", { code = 404 }));
+ return;
end
+
+ -- if handler not called, return 404
+ response.status_code = 404;
+ response:send(events.fire_event("http-error", { code = 404 }));
end
function _M.send_response(response, body)
if response.finished then return; end
@@ -256,6 +262,15 @@ end
function _M.listen_on(port, interface, ssl)
addserver(interface or "*", port, listener, "*a", ssl);
end
+function _M.add_host(host)
+ hosts[host] = true;
+end
+function _M.remove_host(host)
+ hosts[host] = nil;
+end
+function _M.set_default_host(host)
+ default_host = host;
+end
_M.listener = listener;
_M.codes = codes;
diff --git a/plugins/mod_http.lua b/plugins/mod_http.lua
index ef3f0271..c379a562 100644
--- a/plugins/mod_http.lua
+++ b/plugins/mod_http.lua
@@ -10,6 +10,8 @@ module:set_global();
local server = require "net.http.server";
+server.set_default_host(module:get_option_string("http_default_host"));
+
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
@@ -83,6 +85,11 @@ function module.add_host(module)
end
module:handle_items("http-provider", http_app_added, http_app_removed);
+
+ server.add_host(host);
+ function module.unload()
+ server.remove_host(host);
+ end
end
module:add_item("net-provider", {