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
parent 4735:474166c08319
child 4739: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;