mod_admin_telnet: Refactor so that command processing is performed in a separate...
[prosody.git] / plugins / mod_http_files.lua
1 -- Prosody IM
2 -- Copyright (C) 2008-2010 Matthew Wild
3 -- Copyright (C) 2008-2010 Waqas Hussain
4 -- 
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9 module:depends("http");
10 local lfs = require "lfs";
11
12 local open = io.open;
13 local stat = lfs.attributes;
14
15 local http_base = module:get_option_string("http_files_dir", module:get_option_string("http_path", "www_files"));
16
17 -- TODO: Should we read this from /etc/mime.types if it exists? (startup time...?)
18 local mime_map = {
19         html = "text/html";
20         htm = "text/html";
21         xml = "text/xml";
22         xsl = "text/xml";
23         txt = "text/plain; charset=utf-8";
24         js = "text/javascript";
25         css = "text/css";
26 };
27
28 function serve_file(event, path)
29         local response = event.response;
30         local orig_path = event.request.path;
31         local full_path = http_base.."/"..path;
32         if stat(full_path, "mode") == "directory" then
33                 if full_path:sub(-1) ~= "/" then
34                         response.headers.location = orig_path.."/";
35                         return 301;
36                 end
37                 if stat(full_path.."index.html", "mode") == "file" then
38                         return serve_file(event, path.."index.html");
39                 end
40
41                 -- TODO File listing
42                 return 403;
43         end
44         local f, err = open(full_path, "rb");
45         if not f then
46                 module:log("warn", "Failed to open file: %s", err);
47                 return 404;
48         end
49         local data = f:read("*a");
50         f:close();
51         if not data then
52                 return 403;
53         end
54         local ext = path:match("%.([^.]*)$");
55         response.headers.content_type = mime_map[ext]; -- Content-Type should be nil when not known
56         return response:send(data);
57 end
58
59 module:provides("http", {
60         route = {
61                 ["GET /*"] = serve_file;
62         };
63 });
64