Comparison

plugins/mod_httpserver.lua @ 4670:bd5e5e23942a

mod_httpserver: Adapt to use the new HTTP API
author Kim Alvefur <zash@zash.se>
date Mon, 23 Apr 2012 23:36:50 +0200
parent 3353:cd3cbf361f8f
comparison
equal deleted inserted replaced
4669:0e0a72679f77 4670:bd5e5e23942a
4 -- 4 --
5 -- This project is MIT/X11 licensed. Please see the 5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information. 6 -- COPYING file in the source package for more information.
7 -- 7 --
8 8
9 9 module:depends("http");
10 local httpserver = require "net.httpserver";
11 local lfs = require "lfs"; 10 local lfs = require "lfs";
12 11
13 local open = io.open; 12 local open = io.open;
14 local t_concat = table.concat;
15 local stat = lfs.attributes; 13 local stat = lfs.attributes;
16 14
17 local http_base = config.get("*", "core", "http_path") or "www_files"; 15 local http_base = module:get_option_string("http_path", "www_files");
18 16
19 local response_400 = { status = "400 Bad Request", body = "<h1>Bad Request</h1>Sorry, we didn't understand your request :(" }; 17 local response_400 = "<h1>Bad Request</h1>Sorry, we didn't understand your request :(";
20 local response_403 = { status = "403 Forbidden", body = "<h1>Forbidden</h1>You don't have permission to view the contents of this directory :(" }; 18 local response_403 = "<h1>Forbidden</h1>You don't have permission to view the contents of this directory :(";
21 local response_404 = { status = "404 Not Found", body = "<h1>Page Not Found</h1>Sorry, we couldn't find what you were looking for :(" }; 19 local response_404 = "<h1>Page Not Found</h1>Sorry, we couldn't find what you were looking for :(";
22 20
23 -- TODO: Should we read this from /etc/mime.types if it exists? (startup time...?) 21 -- TODO: Should we read this from /etc/mime.types if it exists? (startup time...?)
24 local mime_map = { 22 local mime_map = {
25 html = "text/html"; 23 html = "text/html";
26 htm = "text/html"; 24 htm = "text/html";
47 end 45 end
48 end 46 end
49 return path; 47 return path;
50 end 48 end
51 49
52 function serve_file(path) 50 function serve_file(request, path)
51 local response = request.response;
52 path = path and preprocess_path(path);
53 if not path then
54 response.status = 400;
55 return response:send(response_400);
56 end
53 local full_path = http_base..path; 57 local full_path = http_base..path;
54 if stat(full_path, "mode") == "directory" then 58 if stat(full_path, "mode") == "directory" then
55 if stat(full_path.."/index.html", "mode") == "file" then 59 if stat(full_path.."/index.html", "mode") == "file" then
56 return serve_file(path.."/index.html"); 60 return serve_file(request, path.."/index.html");
57 end 61 end
58 return response_403; 62 response.status = 403;
63 return response:send(response_403);
59 end 64 end
60 local f, err = open(full_path, "rb"); 65 local f, err = open(full_path, "rb");
61 if not f then return response_404; end 66 if not f then
67 response.status = 404;
68 return response:send(response_404.."<br/>"..tostring(err));
69 end
62 local data = f:read("*a"); 70 local data = f:read("*a");
63 f:close(); 71 f:close();
64 if not data then 72 if not data then
65 return response_403; 73 response.status = 403;
74 return response:send(response_403);
66 end 75 end
67 local ext = path:match("%.([^.]*)$"); 76 local ext = path:match("%.([^.]*)$");
68 local mime = mime_map[ext]; -- Content-Type should be nil when not known 77 response.headers.content_type = mime_map[ext]; -- Content-Type should be nil when not known
69 return { 78 return response:send(data);
70 headers = { ["Content-Type"] = mime; };
71 body = data;
72 };
73 end 79 end
74 80
75 local function handle_file_request(method, body, request) 81 module:provides("http", {
76 local path = preprocess_path(request.url.path); 82 route = {
77 if not path then return response_400; end 83 ["/*"] = serve_file;
78 path = path:gsub("^/[^/]+", ""); -- Strip /files/ 84 };
79 return serve_file(path); 85 });
80 end
81 86
82 local function handle_default_request(method, body, request)
83 local path = preprocess_path(request.url.path);
84 if not path then return response_400; end
85 return serve_file(path);
86 end
87
88 local function setup()
89 local ports = config.get(module.host, "core", "http_ports") or { 5280 };
90 httpserver.set_default_handler(handle_default_request);
91 httpserver.new_from_config(ports, handle_file_request, { base = "files" });
92 end
93 if prosody.start_time then -- already started
94 setup();
95 else
96 prosody.events.add_handler("server-started", setup);
97 end