require("luci.httpd.module")
require("luci.http.protocol.date")
require("luci.http.protocol.mime")
+require("luci.http.protocol.conditionals")
require("luci.fs")
require("ltn12")
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