# HG changeset patch
# User Kim Alvefur <zash@zash.se>
# Date 1355263326 -3600
# Node ID 8d116a0cdacdb09df38419e9fb62a343e9941bd4
# Parent  e0373e0dd048985d2b6547fddfbda67c001e97be
mod_http_files: Cache data read from disk in a weak table

diff -r e0373e0dd048 -r 8d116a0cdacd plugins/mod_http_files.lua
--- a/plugins/mod_http_files.lua	Tue Dec 11 22:30:50 2012 +0100
+++ b/plugins/mod_http_files.lua	Tue Dec 11 23:02:06 2012 +0100
@@ -27,6 +27,8 @@
 	css = "text/css";
 };
 
+local cache = setmetatable({}, { __mode = "kv" }); -- Let the garbage collector have it if it wants to.
+
 function serve_file(event, path)
 	local request, response = event.request, event.response;
 	local orig_path = request.path;
@@ -44,7 +46,11 @@
 		return 304;
 	end
 
-	if attr.mode == "directory" then
+	local data = cache[path];
+	if data then
+		response.headers.content_type = data.content_type;
+		data = data.data;
+	elseif attr.mode == "directory" then
 		if full_path:sub(-1) ~= "/" then
 			response.headers.location = orig_path.."/";
 			return 301;
@@ -57,20 +63,19 @@
 
 		-- TODO File listing
 		return 403;
+	else
+		local f = open(full_path, "rb");
+		data = f and f:read("*a");
+		f:close();
+		if not data then
+			return 403;
+		end
+		local ext = path:match("%.([^.]*)$");
+		local content_type = mime_map[ext];
+		cache[path] = { data = data; content_type = content_type; };
+		response.headers.content_type = content_type;
 	end
 
-	local f, err = open(full_path, "rb");
-	if not f then
-		module:log("warn", "Failed to open file: %s", err);
-		return 404;
-	end
-	local data = f:read("*a");
-	f:close();
-	if not data then
-		return 403;
-	end
-	local ext = path:match("%.([^.]*)$");
-	response.headers.content_type = mime_map[ext]; -- Content-Type should be nil when not known
 	return response:send(data);
 end