Mercurial > prosody-hg
comparison net/http/server.lua @ 4736:3514338c59c3
net.http.server, mod_http: Support http_default_host config option to specify where to direct requests for unknown HTTP vhosts
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Fri, 27 Apr 2012 23:11:23 +0100 |
| parents | 474166c08319 |
| children | f1d32a0dc057 |
comparison
equal
deleted
inserted
replaced
| 4735:474166c08319 | 4736:3514338c59c3 |
|---|---|
| 16 local legacy_httpserver = require "net.httpserver"; | 16 local legacy_httpserver = require "net.httpserver"; |
| 17 | 17 |
| 18 local _M = {}; | 18 local _M = {}; |
| 19 | 19 |
| 20 local sessions = {}; | 20 local sessions = {}; |
| 21 | |
| 22 local listener = {}; | 21 local listener = {}; |
| 22 local hosts = {}; | |
| 23 local default_host; | |
| 23 | 24 |
| 24 local function is_wildcard_event(event) | 25 local function is_wildcard_event(event) |
| 25 return event:sub(-2, -1) == "/*"; | 26 return event:sub(-2, -1) == "/*"; |
| 26 end | 27 end |
| 27 local function is_wildcard_match(wildcard_event, event) | 28 local function is_wildcard_match(wildcard_event, event) |
| 167 send = _M.send_response; | 168 send = _M.send_response; |
| 168 finish_cb = finish_cb; | 169 finish_cb = finish_cb; |
| 169 }; | 170 }; |
| 170 conn._http_open_response = response; | 171 conn._http_open_response = response; |
| 171 | 172 |
| 172 local err; | 173 local host = (request.headers.host or ""):match("[^:]+"); |
| 173 if not request.headers.host then | 174 |
| 174 err = "No 'Host' header"; | 175 -- Some sanity checking |
| 176 local err_code, err; | |
| 177 if not host then | |
| 178 err_code, err = 400, "Missing or invalid 'Host' header"; | |
| 175 elseif not request.path then | 179 elseif not request.path then |
| 176 err = "Invalid path"; | 180 err_code, err = 400, "Invalid path"; |
| 181 end | |
| 182 if not hosts[host] then | |
| 183 if hosts[default_host] then | |
| 184 host = default_host; | |
| 185 else | |
| 186 err_code, err = 404, "Unknown host: "..host; | |
| 187 end | |
| 177 end | 188 end |
| 178 | 189 |
| 179 if err then | 190 if err then |
| 180 response.status_code = 400; | 191 response.status_code = err_code; |
| 181 response.headers.content_type = "text/html"; | 192 response:send(events.fire_event("http-error", { code = err_code, message = err })); |
| 182 response:send(events.fire_event("http-error", { code = 400, message = err })); | 193 return; |
| 183 else | 194 end |
| 184 local host = request.headers.host; | 195 |
| 185 if host then | 196 local event = request.method.." "..host..request.path:match("[^?]*"); |
| 186 host = host:match("[^:]*"):lower(); | 197 local payload = { request = request, response = response }; |
| 187 local event = request.method.." "..host..request.path:match("[^?]*"); | 198 --log("debug", "Firing event: %s", event); |
| 188 local payload = { request = request, response = response }; | 199 local result = events.fire_event(event, payload); |
| 189 --log("debug", "Firing event: %s", event); | 200 if result ~= nil then |
| 190 local result = events.fire_event(event, payload); | 201 if result ~= true then |
| 191 if result ~= nil then | 202 local code, body = 200, ""; |
| 192 if result ~= true then | 203 local result_type = type(result); |
| 193 local code, body = 200, ""; | 204 if result_type == "number" then |
| 194 local result_type = type(result); | 205 response.status_code = result; |
| 195 if result_type == "number" then | 206 if result >= 400 then |
| 196 response.status_code = result; | 207 body = events.fire_event("http-error", { code = result }); |
| 197 if result >= 400 then | 208 end |
| 198 body = events.fire_event("http-error", { code = result }); | 209 elseif result_type == "string" then |
| 199 end | 210 body = result; |
| 200 elseif result_type == "string" then | 211 elseif result_type == "table" then |
| 201 body = result; | 212 body = result.body; |
| 202 elseif result_type == "table" then | 213 result.body = nil; |
| 203 body = result.body; | 214 for k, v in pairs(result) do |
| 204 result.body = nil; | 215 response[k] = v; |
| 205 for k, v in pairs(result) do | 216 end |
| 206 response[k] = v; | 217 end |
| 207 end | 218 response:send(body); |
| 208 end | 219 end |
| 209 response:send(body); | 220 return; |
| 210 end | 221 end |
| 211 return; | 222 |
| 212 end | 223 -- if handler not called, return 404 |
| 213 end | 224 response.status_code = 404; |
| 214 | 225 response:send(events.fire_event("http-error", { code = 404 })); |
| 215 -- if handler not called, return 404 | |
| 216 response.status_code = 404; | |
| 217 response.headers.content_type = "text/html"; | |
| 218 response:send(events.fire_event("http-error", { code = 404 })); | |
| 219 end | |
| 220 end | 226 end |
| 221 function _M.send_response(response, body) | 227 function _M.send_response(response, body) |
| 222 if response.finished then return; end | 228 if response.finished then return; end |
| 223 response.finished = true; | 229 response.finished = true; |
| 224 response.conn._http_open_response = nil; | 230 response.conn._http_open_response = nil; |
| 254 end | 260 end |
| 255 | 261 |
| 256 function _M.listen_on(port, interface, ssl) | 262 function _M.listen_on(port, interface, ssl) |
| 257 addserver(interface or "*", port, listener, "*a", ssl); | 263 addserver(interface or "*", port, listener, "*a", ssl); |
| 258 end | 264 end |
| 265 function _M.add_host(host) | |
| 266 hosts[host] = true; | |
| 267 end | |
| 268 function _M.remove_host(host) | |
| 269 hosts[host] = nil; | |
| 270 end | |
| 271 function _M.set_default_host(host) | |
| 272 default_host = host; | |
| 273 end | |
| 259 | 274 |
| 260 _M.listener = listener; | 275 _M.listener = listener; |
| 261 _M.codes = codes; | 276 _M.codes = codes; |
| 262 _M._events = events; | 277 _M._events = events; |
| 263 return _M; | 278 return _M; |
