diff options
author | Matthew Wild <mwild1@gmail.com> | 2012-04-27 23:11:23 +0100 |
---|---|---|
committer | Matthew Wild <mwild1@gmail.com> | 2012-04-27 23:11:23 +0100 |
commit | fb9c619707409485b4b1afbd5585785759c6922d (patch) | |
tree | 490a1c1038ac91d4f0b047faf54f9ea77980196f | |
parent | 987c79e4d0cbf7c35a6201603813a3a0ff491db2 (diff) | |
download | prosody-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.lua | 97 | ||||
-rw-r--r-- | plugins/mod_http.lua | 7 |
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", { |