mod_http_files: send valid ETag header
[prosody.git] / plugins / mod_http_files.lua
index 6275cca5d7fc2a07fc072cd9b53587fe2fabeef7..40f46c9cf8b9dc524f6c643731b1e2c5e9cf8a60 100644 (file)
@@ -1,7 +1,7 @@
 -- Prosody IM
 -- Copyright (C) 2008-2010 Matthew Wild
 -- Copyright (C) 2008-2010 Waqas Hussain
--- 
+--
 -- This project is MIT/X11 licensed. Please see the
 -- COPYING file in the source package for more information.
 --
@@ -56,6 +56,7 @@ end
 
 local urldecode = require "util.http".urldecode;
 function sanitize_path(path)
+       if not path then return end
        local out = {};
 
        local c = 0;
@@ -74,6 +75,9 @@ function sanitize_path(path)
                        out[c] = component;
                end
        end
+       if path:sub(-1,-1) == "/" then
+               out[c+1] = "";
+       end
        return "/"..table.concat(out, "/");
 end
 
@@ -88,12 +92,13 @@ function serve(opts)
        local directory_index = opts.directory_index;
        local function serve_file(event, path)
                local request, response = event.request, event.response;
-               path = sanitize_path(path);
-               if not path then
+               local sanitized_path = sanitize_path(path);
+               if path and not sanitized_path then
                        return 400;
                end
+               path = sanitized_path;
                local orig_path = sanitize_path(request.path);
-               local full_path = base_path .. (path and "/"..path or ""):gsub("/", path_sep);
+               local full_path = base_path .. (path or ""):gsub("/", path_sep);
                local attr = stat(full_path:match("^.*[^\\/]")); -- Strip trailing path separator because Windows
                if not attr then
                        return 404;
@@ -104,7 +109,7 @@ function serve(opts)
                local last_modified = os_date('!%a, %d %b %Y %H:%M:%S GMT', attr.modification);
                response_headers.last_modified = last_modified;
 
-               local etag = ("%02x-%x-%x-%x"):format(attr.dev or 0, attr.ino or 0, attr.size or 0, attr.modification or 0);
+               local etag = ('"%02x-%x-%x-%x"'):format(attr.dev or 0, attr.ino or 0, attr.size or 0, attr.modification or 0);
                response_headers.etag = etag;
 
                local if_none_match = request_headers.if_none_match