* libs/http: fix header handling in conditionals.lua
[project/luci.git] / libs / httpd / luasrc / httpd / handler / file.lua
index e6311e8..790ebdd 100644 (file)
@@ -18,6 +18,7 @@ module("luci.httpd.handler.file", package.seeall)
 require("luci.httpd.module")
 require("luci.http.protocol.date")
 require("luci.http.protocol.mime")
+require("luci.http.protocol.conditionals")
 require("luci.fs")
 require("ltn12")
 
@@ -30,39 +31,62 @@ function Simple.__init__(self, docroot, dirlist)
        self.dirlist = dirlist and true or false
        self.mime    = luci.http.protocol.mime
        self.date    = luci.http.protocol.date
+       self.cond    = luci.http.protocol.conditionals
 end
 
 function Simple.getfile(self, uri)
-       local file = self.docroot .. uri:gsub("%.%./", "")
+       local file = self.docroot .. uri:gsub("%.%./+", "")
        local stat = luci.fs.stat(file)
 
        return file, stat
 end
 
-
-function Simple._mk_etag(self, stat)
-       return string.format( "%x-%x-%x", stat.ino, stat.size, stat.mtime )
-end
-
-function Simple._cmp_etag(self, stat, etag)
-       return ( self:_mk_etag(stat) == etag )
-end
-
-
 function Simple.handle_get(self, request, sourcein, sinkerr)
        local file, stat = self:getfile(request.env.PATH_INFO)
 
        if stat then
                if stat.type == "regular" then
-                       return Response(
-                               200, {
-                                       ["Date"]           = self.date.to_http( os.time() );
-                                       ["Last-Modified"]  = self.date.to_http( stat.mtime );
-                                       ["Content-Type"]   = self.mime.to_mime( file );
-                                       ["Content-Length"] = stat.size;
-                                       ["ETag"]           = self:_mk_etag( stat );
-                               }
-                       ), ltn12.source.file(io.open(file))
+
+                       -- Generate Entity Tag
+                       local etag = self.cond.mk_etag( stat )
+
+                       -- Check conditionals
+                       local ok, code, hdrs
+
+                       ok, code, hdrs = self.cond.if_modified_since( request, stat )
+                       if ok then
+                               ok, code, hdrs = self.cond.if_match( request, stat )
+                               if ok then
+                                       ok, code, hdrs = self.cond.if_unmodified_since( request, stat )
+                                       if ok then
+                                               ok, code, hdrs = self.cond.if_none_match( request, stat )
+                                               if ok then
+                                                       -- Send Response
+                                                       return Response(
+                                                               200, {
+                                                                       ["Date"]           = self.date.to_http( os.time() );
+                                                                       ["Last-Modified"]  = self.date.to_http( stat.mtime );
+                                                                       ["Content-Type"]   = self.mime.to_mime( file );
+                                                                       ["Content-Length"] = stat.size;
+                                                                       ["ETag"]           = etag;
+                                                               }
+                                                       ), ltn12.source.file(io.open(file))
+                                               else
+                                                       return Response( code, hdrs or { } ),
+                                                               ltn12.source.empty()
+                                               end
+                                       else
+                                               return Response( code, hdrs or { } ),
+                                                       ltn12.source.empty()
+                                       end
+                               else
+                                       return Response( code, hdrs or { } ),
+                                               ltn12.source.empty()
+                               end
+                       else
+                               return Response( code, hdrs or { } ),
+                                       ltn12.source.empty()
+                       end
                else
                        return self:failure(403, "Unable to transmit " .. stat.type .. " " .. file)
                end