summaryrefslogtreecommitdiffhomepage
path: root/libs
diff options
context:
space:
mode:
authorJo-Philipp Wich <jow@openwrt.org>2008-06-28 02:05:48 +0000
committerJo-Philipp Wich <jow@openwrt.org>2008-06-28 02:05:48 +0000
commit7f56bf947599b20e2cf50018e160e602d5516e5f (patch)
tree45eade5287d340d2d6883aaa39e0fa3a1e57204e /libs
parent3eefe8a8e2f9270ffc7b83744f692ee34852e4a1 (diff)
* libs/http: prepare support for RFC2616 / 14.24 - 14.28
Diffstat (limited to 'libs')
-rw-r--r--libs/http/luasrc/http/protocol/conditionals.lua111
-rw-r--r--libs/httpd/luasrc/httpd/handler/file.lua18
2 files changed, 118 insertions, 11 deletions
diff --git a/libs/http/luasrc/http/protocol/conditionals.lua b/libs/http/luasrc/http/protocol/conditionals.lua
new file mode 100644
index 0000000000..0bff274cda
--- /dev/null
+++ b/libs/http/luasrc/http/protocol/conditionals.lua
@@ -0,0 +1,111 @@
+--[[
+
+HTTP protocol implementation for LuCI - RFC2616 / 14.19, 14.24 - 14.28
+(c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+$Id$
+
+]]--
+
+module("luci.http.protocol.conditionals", package.seeall)
+
+local date = require("luci.http.protocol.date")
+
+
+-- 14.19 / ETag
+function mk_etag( stat )
+ if stat ~= nil then
+ return string.format( "%x-%x-%x", stat.ino, stat.size, stat.mtime )
+ end
+end
+
+-- 14.24 / If-Match
+function if_match( req, stat )
+ local h = req.headers
+ local etag = mk_etag( stat )
+
+ -- Check for matching resource
+ if type(h['If-Match']) == "string" then
+ for ent in h['If-Match']:gmatch("([^, ]+)") do
+ if ( ent == '*' or ent == etag ) and stat ~= nil then
+ return true
+ end
+ end
+
+ return false, 412
+ end
+
+ return true
+end
+
+-- 14.25 / If-Modified-Since
+function if_modified_since( req, stat )
+ local h = req.headers
+
+ -- Compare mtimes
+ if type(h['If-Modified-Since']) == "string" then
+ local since = date.to_unix( h['If-Modified-Since'] )
+
+ if stat == nil or since < stat.mtime then
+ return true
+ end
+
+ return false, 304
+ end
+
+ return true
+end
+
+-- 14.26 / If-None-Match
+function if_none_match( req, stat )
+ local h = req.headers
+ local etag = mk_etag( stat )
+
+ -- Check for matching resource
+ if type(h['If-None-Match']) == "string" then
+ for ent in h['If-None-Match']:gmatch("([^, ]+)") do
+ if ( ent == '*' or ent == etag ) and stat ~= nil then
+ if req.request_method == "get" or
+ req.request_method == "head"
+ then
+ h['ETag'] = mk_etag( stat )
+ h['Last-Modified'] = date.to_http( stat.mtime )
+
+ return false, 304
+ else
+ return false, 412
+ end
+ end
+ end
+ end
+
+ return true
+end
+
+-- 14.27 / If-Range
+function if_range( req, stat )
+ -- Sorry, no subranges (yet)
+ return false, 412
+end
+
+-- 14.28 / If-Unmodified-Since
+function if_unmodified_since( req, stat )
+ local h = req.headers
+
+ -- Compare mtimes
+ if type(h['If-Unmodified-Since']) == "string" then
+ local since = date.to_unix( h['If-Unmodified-Since'] )
+
+ if stat ~= nil and since <= stat.mtime then
+ return false, 412
+ end
+ end
+
+ return true
+end
diff --git a/libs/httpd/luasrc/httpd/handler/file.lua b/libs/httpd/luasrc/httpd/handler/file.lua
index e6311e839f..f553e8292a 100644
--- a/libs/httpd/luasrc/httpd/handler/file.lua
+++ b/libs/httpd/luasrc/httpd/handler/file.lua
@@ -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")
@@ -39,28 +40,23 @@ function Simple.getfile(self, uri)
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
+
+ -- Generate Entity Tag
+ local etag = luci.http.protocol.conditionals.mk_etag( stat )
+
+ -- 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"] = self:_mk_etag( stat );
+ ["ETag"] = etag;
}
), ltn12.source.file(io.open(file))
else