Mercurial > prosody-hg
comparison plugins/mod_http_files.lua @ 5236:8d116a0cdacd
mod_http_files: Cache data read from disk in a weak table
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Tue, 11 Dec 2012 23:02:06 +0100 |
| parents | e0373e0dd048 |
| children | b1038f449e15 |
comparison
equal
deleted
inserted
replaced
| 5235:e0373e0dd048 | 5236:8d116a0cdacd |
|---|---|
| 25 txt = "text/plain; charset=utf-8"; | 25 txt = "text/plain; charset=utf-8"; |
| 26 js = "text/javascript"; | 26 js = "text/javascript"; |
| 27 css = "text/css"; | 27 css = "text/css"; |
| 28 }; | 28 }; |
| 29 | 29 |
| 30 local cache = setmetatable({}, { __mode = "kv" }); -- Let the garbage collector have it if it wants to. | |
| 31 | |
| 30 function serve_file(event, path) | 32 function serve_file(event, path) |
| 31 local request, response = event.request, event.response; | 33 local request, response = event.request, event.response; |
| 32 local orig_path = request.path; | 34 local orig_path = request.path; |
| 33 local full_path = http_base.."/"..path; | 35 local full_path = http_base.."/"..path; |
| 34 local attr = stat(full_path); | 36 local attr = stat(full_path); |
| 42 response.headers.etag = tag; | 44 response.headers.etag = tag; |
| 43 if tag == request.headers.if_none_match then | 45 if tag == request.headers.if_none_match then |
| 44 return 304; | 46 return 304; |
| 45 end | 47 end |
| 46 | 48 |
| 47 if attr.mode == "directory" then | 49 local data = cache[path]; |
| 50 if data then | |
| 51 response.headers.content_type = data.content_type; | |
| 52 data = data.data; | |
| 53 elseif attr.mode == "directory" then | |
| 48 if full_path:sub(-1) ~= "/" then | 54 if full_path:sub(-1) ~= "/" then |
| 49 response.headers.location = orig_path.."/"; | 55 response.headers.location = orig_path.."/"; |
| 50 return 301; | 56 return 301; |
| 51 end | 57 end |
| 52 for i=1,#dir_indices do | 58 for i=1,#dir_indices do |
| 55 end | 61 end |
| 56 end | 62 end |
| 57 | 63 |
| 58 -- TODO File listing | 64 -- TODO File listing |
| 59 return 403; | 65 return 403; |
| 66 else | |
| 67 local f = open(full_path, "rb"); | |
| 68 data = f and f:read("*a"); | |
| 69 f:close(); | |
| 70 if not data then | |
| 71 return 403; | |
| 72 end | |
| 73 local ext = path:match("%.([^.]*)$"); | |
| 74 local content_type = mime_map[ext]; | |
| 75 cache[path] = { data = data; content_type = content_type; }; | |
| 76 response.headers.content_type = content_type; | |
| 60 end | 77 end |
| 61 | 78 |
| 62 local f, err = open(full_path, "rb"); | |
| 63 if not f then | |
| 64 module:log("warn", "Failed to open file: %s", err); | |
| 65 return 404; | |
| 66 end | |
| 67 local data = f:read("*a"); | |
| 68 f:close(); | |
| 69 if not data then | |
| 70 return 403; | |
| 71 end | |
| 72 local ext = path:match("%.([^.]*)$"); | |
| 73 response.headers.content_type = mime_map[ext]; -- Content-Type should be nil when not known | |
| 74 return response:send(data); | 79 return response:send(data); |
| 75 end | 80 end |
| 76 | 81 |
| 77 module:provides("http", { | 82 module:provides("http", { |
| 78 route = { | 83 route = { |
