From d7697624c4953898e0e3b60ac72c0ba777c47a2b Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Mon, 30 Jun 2008 11:52:23 +0000 Subject: * libs/http: removed protocol.filter, added mimetypes to protocol.mime * libs/httpd: handle missing permissions correctly, perform urldecode on request uri and urlencode on generated links, added css --- libs/http/luasrc/http/protocol.lua | 5 +- libs/http/luasrc/http/protocol/filter.lua | 81 ------------------------------- libs/http/luasrc/http/protocol/mime.lua | 28 +++++++++++ libs/httpd/luasrc/httpd/handler/file.lua | 75 ++++++++++++++++++---------- 4 files changed, 80 insertions(+), 109 deletions(-) delete mode 100644 libs/http/luasrc/http/protocol/filter.lua (limited to 'libs') diff --git a/libs/http/luasrc/http/protocol.lua b/libs/http/luasrc/http/protocol.lua index ac5857889..93851fb05 100644 --- a/libs/http/luasrc/http/protocol.lua +++ b/libs/http/luasrc/http/protocol.lua @@ -16,7 +16,6 @@ $Id$ module("luci.http.protocol", package.seeall) local ltn12 = require("luci.ltn12") -require("luci.http.protocol.filter") HTTP_MAX_CONTENT = 1024*4 -- 4 kB maximum content size HTTP_URLENC_MAXKEYLEN = 1024 -- maximum allowd size of urlencoded parameter names @@ -31,7 +30,7 @@ function urldecode( str ) end if type(str) == "string" then - str = str:gsub( "+", " " ):gsub( "%%([a-fA-F0-9][a-fA-F0-9])", __chrdec ) + str = str:gsub( "%%([a-fA-F0-9][a-fA-F0-9])", __chrdec ) end return str @@ -84,7 +83,7 @@ function urlencode( str ) if type(str) == "string" then str = str:gsub( - "([^a-zA-Z0-9$_%-%.+!*'(),])", + "([^a-zA-Z0-9$_%-%.%+!*'(),])", __chrenc ) end diff --git a/libs/http/luasrc/http/protocol/filter.lua b/libs/http/luasrc/http/protocol/filter.lua deleted file mode 100644 index de106aae4..000000000 --- a/libs/http/luasrc/http/protocol/filter.lua +++ /dev/null @@ -1,81 +0,0 @@ ---[[ - -HTTP protocol implementation for LuCI - filter implementation -(c) 2008 Freifunk Leipzig / Jo-Philipp Wich - -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.filter", package.seeall) - -local ltn12 = require("luci.ltn12") - - --- Factory that produces a filter which normalizes chunked transfer encoding -function decode_chunked() - - local length = 0 - local read = 0 - - return ltn12.filter.cycle( - function( chunk, ctx ) - - if chunk ~= nil then - - -- EOF - if ctx == nil then - if ( length - read ) > 0 then - return nil, "Unexpected EOF" - else - return "" - end - end - - chunk = ctx .. chunk - - local buf = "" - while true do - - if read == length then - - -- Find chunk length indicator - local spos, epos = chunk:find("^\r?\n?[a-fA-F0-9]+ *\r\n") - if spos and spos == 1 then - read = 0 - length = tonumber( - chunk:sub( 1, epos ):gsub( "[^a-fA-F0-9]", "" ), 16 - ) - - -- Check for end of chunk - if length > 0 then - chunk = chunk:sub( epos + 1, #chunk ) - else - return buf, "" - end - else - return "", nil - end - else - if ( read + #chunk ) <= length then - read = read + #chunk - return buf .. chunk, "" - else - local rest = length - read - read = read + rest - buf = buf .. chunk:sub( 1, rest ) - chunk = chunk:sub( rest + 1, #chunk ) - end - end - end - end - end, - "" - ) -end diff --git a/libs/http/luasrc/http/protocol/mime.lua b/libs/http/luasrc/http/protocol/mime.lua index 7f09f943b..9fb8d256d 100644 --- a/libs/http/luasrc/http/protocol/mime.lua +++ b/libs/http/luasrc/http/protocol/mime.lua @@ -25,13 +25,41 @@ MIME_TYPES = { ["css"] = "text/css"; ["htm"] = "text/html"; ["html"] = "text/html"; + ["patch"] = "text/x-patch"; + ["c"] = "text/x-csrc"; + ["h"] = "text/x-chdr"; + ["o"] = "text/x-object"; + ["ko"] = "text/x-object"; + ["bmp"] = "image/bmp"; ["gif"] = "image/gif"; ["png"] = "image/png"; ["jpg"] = "image/jpeg"; ["jpeg"] = "image/jpeg"; + ["svg"] = "image/svg+xml"; + ["zip"] = "application/zip"; + ["pdf"] = "application/pdf"; ["xml"] = "application/xml"; + ["doc"] = "application/msword"; + ["ppt"] = "application/vnd.ms-powerpoint"; + ["xls"] = "application/vnd.ms-excel"; + ["odt"] = "application/vnd.oasis.opendocument.text"; + ["odp"] = "application/vnd.oasis.opendocument.presentation"; + ["pl"] = "application/x-perl"; + ["sh"] = "application/x-shellscript"; + ["php"] = "application/x-php"; + ["deb"] = "application/x-deb"; + ["iso"] = "application/x-cd-image"; + ["tgz"] = "application/x-compressed-tar"; + + ["mp3"] = "audio/mpeg"; + ["ogg"] = "audio/x-vorbis+ogg"; + ["wav"] = "audio/x-wav"; + + ["mpg"] = "video/mpeg"; + ["mpeg"] = "video/mpeg"; + ["avi"] = "video/x-msvideo"; } -- extract extension from a filename and return corresponding mime-type or diff --git a/libs/httpd/luasrc/httpd/handler/file.lua b/libs/httpd/luasrc/httpd/handler/file.lua index 80282631e..4cbfa412c 100644 --- a/libs/httpd/luasrc/httpd/handler/file.lua +++ b/libs/httpd/luasrc/httpd/handler/file.lua @@ -30,6 +30,7 @@ function Simple.__init__(self, docroot, dirlist) luci.httpd.module.Handler.__init__(self) self.docroot = docroot self.dirlist = dirlist and true or false + self.proto = luci.http.protocol self.mime = luci.http.protocol.mime self.date = luci.http.protocol.date self.cond = luci.http.protocol.conditionals @@ -43,7 +44,7 @@ function Simple.getfile(self, uri) end function Simple.handle_get(self, request, sourcein, sinkerr) - local file, stat = self:getfile(request.env.PATH_INFO) + local file, stat = self:getfile( self.proto.urldecode( request.env.PATH_INFO ) ) if stat then if stat.type == "regular" then @@ -62,16 +63,22 @@ function Simple.handle_get(self, request, sourcein, sinkerr) 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)) + local f, err = io.open(file) + + if f 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(f) + else + return self:failure( 403, err:gsub("^.+: ", "") ) + end else return Response( code, hdrs or { } ) end @@ -88,6 +95,7 @@ function Simple.handle_get(self, request, sourcein, sinkerr) elseif stat.type == "directory" then local ruri = request.request_uri:gsub("/$","") + local duri = self.proto.urldecode( ruri ) local root = self.docroot:gsub("/$","") -- check for index files @@ -99,7 +107,7 @@ function Simple.handle_get(self, request, sourcein, sinkerr) -- try to find an index file and redirect to it for i, candidate in ipairs( index_candidates ) do local istat = luci.fs.stat( - root .. "/" .. ruri .. "/" .. candidate + root .. "/" .. duri .. "/" .. candidate ) if istat ~= nil and istat.type == "regular" then @@ -111,36 +119,53 @@ function Simple.handle_get(self, request, sourcein, sinkerr) local html = string.format( - '\n' .. + '\n' .. '\n' .. '\n' .. '\n' .. - 'Index of %s/\n' .. - '

Index of %s/