Class: merged in from tekUI; Buffer, FastCGI, Request, Post, Loona: Adapted to
authorTimm S. Mueller <tmueller@neoscientists.org>
Sat, 13 Sep 2008 15:57:41 +0200
changeset 2469378039084bd
parent 245 c2fd74f770ef
child 247 71a5ca44a68e
Class: merged in from tekUI; Buffer, FastCGI, Request, Post, Loona: Adapted to
work with proxied object model
cgi-bin/loona_fastcgi.lua
cgi-bin/tek/class.lua
cgi-bin/tek/class/cgi/post.lua
cgi-bin/tek/class/cgi/request.lua
cgi-bin/tek/class/fastcgi.lua
cgi-bin/tek/class/loona.lua
cgi-bin/tek/class/loona/buffer.lua
     1.1 --- a/cgi-bin/loona_fastcgi.lua	Fri Sep 12 22:14:53 2008 +0200
     1.2 +++ b/cgi-bin/loona_fastcgi.lua	Sat Sep 13 15:57:41 2008 +0200
     1.3 @@ -37,7 +37,7 @@
     1.4  --	FCGI Buffer class:
     1.5  -------------------------------------------------------------------------------
     1.6  
     1.7 -local FCGIBuffer = Buffer:newClass()
     1.8 +local FCGIBuffer = Buffer:newClass { _NAME = "_fcgibuffer" }
     1.9  
    1.10  function FCGIBuffer:flush()
    1.11  	local fcgi = self.fcgi
    1.12 @@ -55,7 +55,15 @@
    1.13  --	FCGI Server class:
    1.14  -------------------------------------------------------------------------------
    1.15  
    1.16 -local FCGIServer = FCGI:newClass()
    1.17 +local FCGIServer = FCGI:newClass { _NAME = "_fcgiserver" }
    1.18 +
    1.19 +function FCGIServer.new(class, self)
    1.20 +	self = self or { }
    1.21 +	self.buffer = false
    1.22 +	self.document = false
    1.23 +	self.request = false
    1.24 +	return FCGI.new(class, self)
    1.25 +end
    1.26  
    1.27  function FCGIServer:runapp(req)
    1.28  	loona.main(self.buffer, self.request, self.document, self.userdata)
    1.29 @@ -75,7 +83,8 @@
    1.30  
    1.31  function FCGIServer:have_params(req, params)
    1.32  
    1.33 -	self.request = Request:new {
    1.34 +	self.request = Request:new
    1.35 +	{
    1.36  		maxinput = MAX_CONTENT_LENGTH,
    1.37  		maxfilesize = MAX_FILESIZE,
    1.38  		getenv = function(name)
     2.1 --- a/cgi-bin/tek/class.lua	Fri Sep 12 22:14:53 2008 +0200
     2.2 +++ b/cgi-bin/tek/class.lua	Sat Sep 13 15:57:41 2008 +0200
     2.3 @@ -1,49 +1,153 @@
     2.4  -------------------------------------------------------------------------------
     2.5  --
     2.6  --	tek.class
     2.7 ---	Written by Timm S. Mueller <tmueller@neoscientists.org>
     2.8 +--	Written by Timm S. Mueller <tmueller at schulze-mueller.de>
     2.9  --	See copyright notice in COPYRIGHT
    2.10  --
    2.11 +--	LINEAGE::
    2.12 +--		[[#ClassOverview]] :
    2.13 +--		Class
    2.14 +--
    2.15  --	OVERVIEW::
    2.16 ---	Class implements class inheritance and the creation of objects.
    2.17 +--		This module implements inheritance and the creation of objects
    2.18 +--		from classes.
    2.19 +--
    2.20 +--	IMPLEMENTS::
    2.21 +--		- Class:checkDescend() - Checks if an object descends from a class
    2.22 +--		- Class:getClass() - Returns the class of an object, or the super
    2.23 +--		class of a class
    2.24 +--		- Class:getClassName() - Returns class name of an object or class
    2.25 +--		- Class:getSuper() - Returns the super class of an object or class
    2.26 +--		- Class.new() - Creates and returns a new object
    2.27 +--		- Class.newClass() - Creates a child class from a super class
    2.28 +--		- Class:setClass() - Changes the class of an object, or the super
    2.29 +--		class of a class
    2.30  --
    2.31  -------------------------------------------------------------------------------
    2.32  
    2.33 +local error = error
    2.34  local tostring = tostring
    2.35  local getmetatable = getmetatable
    2.36  local setmetatable = setmetatable
    2.37  
    2.38 +-- use proxied object model:
    2.39 +local PROXY = true
    2.40 +-- in proxied mode, trace uninitialized variable accesses:
    2.41 +local DEBUG = true
    2.42 +
    2.43  module "tek.class"
    2.44 -_VERSION = "Class 2.5"
    2.45 +_VERSION = "Class 6.2"
    2.46  
    2.47  local Class = _M
    2.48  
    2.49  Class.__index = _M
    2.50  
    2.51 +if PROXY then
    2.52 +
    2.53 +	function Class.new(class, self)
    2.54 +		self = self or { }
    2.55 +
    2.56 +		local mt = { __class = class }
    2.57 +
    2.58 +		if DEBUG then
    2.59 +			function mt.__index(tab, key)
    2.60 +				local val = mt[key]
    2.61 +				if not val then
    2.62 +					error(("Uninitialized read: %s.%s"):format(
    2.63 +						tab:getClassName(), key), 2)
    2.64 +				end
    2.65 +				return val
    2.66 +			end
    2.67 +			function mt.__newindex(tab, key, val)
    2.68 +				error(("Uninitialized write: %s.%s=%s"):format(
    2.69 +					tab:getClassName(), key,
    2.70 +					tostring(val)), 2)
    2.71 +				mt[key] = val
    2.72 +			end
    2.73 +		else
    2.74 +			mt.__index = mt
    2.75 +			mt.__newindex = mt
    2.76 +		end
    2.77 +
    2.78 +		setmetatable(mt, class)
    2.79 +		return setmetatable(self, mt)
    2.80 +	end
    2.81 +
    2.82 +	function Class:getClass()
    2.83 +		mt = getmetatable(self)
    2.84 +		return mt.__class or mt
    2.85 +	end
    2.86 +
    2.87 +	function Class:setClass(class)
    2.88 +		mt = getmetatable(self)
    2.89 +		mt.__class = class
    2.90 +		setmetatable(mt, class)
    2.91 +	end
    2.92 +
    2.93 +	function Class:getSuper()
    2.94 +		return getmetatable(self.__class or self)
    2.95 +	end
    2.96 +
    2.97 +else
    2.98 +
    2.99  -------------------------------------------------------------------------------
   2.100 ---	object = new(class[, object]):
   2.101 ---	Creates and returns a new object of the given class. Optionally, it just
   2.102 ---	prepares the specified table {{object}} for inheritance and attaches the
   2.103 ---	class methods and data.
   2.104 +--	object = Class.new(class[, object]):
   2.105 +--	Creates and returns a new object of the given {{class}}. Optionally,
   2.106 +--	it just prepares the specified table {{object}} for inheritance and
   2.107 +--	attaches the class methods and data.
   2.108  -------------------------------------------------------------------------------
   2.109  
   2.110 -function Class.new(class, self)
   2.111 -	return setmetatable(self or { }, class)
   2.112 +	function Class.new(class, self)
   2.113 +		return setmetatable(self or { }, class)
   2.114 +	end
   2.115 +
   2.116 +-------------------------------------------------------------------------------
   2.117 +--	class = object:getClass():
   2.118 +--	This function returns the class of the specified object. If applied to
   2.119 +--	a class instead of an object, it returns its super class, e.g.:
   2.120 +--			superclass = Class.getClass(class)
   2.121 +-------------------------------------------------------------------------------
   2.122 +
   2.123 +	function Class:getClass()
   2.124 +		return getmetatable(self)
   2.125 +	end
   2.126 +
   2.127 +-------------------------------------------------------------------------------
   2.128 +--	object:setClass(class): Changes the class of an object
   2.129 +--	or the super class of a class.
   2.130 +-------------------------------------------------------------------------------
   2.131 +
   2.132 +	function Class:setClass(class)
   2.133 +		setmetatable(self, class)
   2.134 +	end
   2.135 +
   2.136 +-------------------------------------------------------------------------------
   2.137 +--	object:getSuper(): Gets the super class of an object (or class).
   2.138 +--	For example, this is how a call to method can be forwarded to its
   2.139 +--	super class:
   2.140 +--			self:getSuper().method(self, ...)
   2.141 +-------------------------------------------------------------------------------
   2.142 +
   2.143 +	function Class:getSuper()
   2.144 +		return getmetatable(self.__index or getmetatable(self))
   2.145 +	end
   2.146 +
   2.147  end
   2.148  
   2.149  -------------------------------------------------------------------------------
   2.150 ---	class = newClass(superclass[, class]):
   2.151 ---	Derives a new class from the specified superclass. Optionally, an existing
   2.152 ---	table can be used for {{class}}. In this case, if a {{_NAME}} attribute
   2.153 ---	exists in the class table, it will be used. Otherwise, or if a new class
   2.154 ---	is created, {{class._NAME}} will be composed from {{superclass._NAME}}
   2.155 ---	and an unique identifier. The same functionality can be achieved by
   2.156 ---	calling a class like a function, so these two invocations are equivalent:
   2.157 ---			class = newClass(superclass)
   2.158 +--	class = Class.newClass(superclass[, class]):
   2.159 +--	Derives a new class from the specified {{superclass}}. Optionally,
   2.160 +--	an existing class table can be used. In this case, if a {{_NAME}}
   2.161 +--	attribute exists in the class table, it will be used. Otherwise, or if
   2.162 +--	a new class is being created, {{class._NAME}} will be composed from
   2.163 +--	{{superclass._NAME}} and an unique identifier. The same functionality
   2.164 +--	can be achieved by calling a class like a function, so these invocations
   2.165 +--	are equivalent:
   2.166 +--			class = Class.newClass(superclass)
   2.167  --			class = superclass()
   2.168 ---	The second notation allows a superclass to be passed (as the second
   2.169 ---	argument) to Lua's {{module}} function, which will set up a child class
   2.170 ---	in the module table inheriting from {{superclass}}.
   2.171 +--	The second notation allows a super class to be passed as the second
   2.172 +--	argument to Lua's {{module}} function, which will set up a child class
   2.173 +--	inheriting from {{superclass}} in the module table.
   2.174  -------------------------------------------------------------------------------
   2.175  
   2.176  function Class.newClass(superclass, class)
   2.177 @@ -56,17 +160,8 @@
   2.178  end
   2.179  
   2.180  -------------------------------------------------------------------------------
   2.181 ---	class = object:getClass():
   2.182 ---	This function returns the class of the specified object.
   2.183 --------------------------------------------------------------------------------
   2.184 -
   2.185 -function Class:getClass()
   2.186 -	return getmetatable(self)
   2.187 -end
   2.188 -
   2.189 --------------------------------------------------------------------------------
   2.190 ---	class = object:getClassName(): This function returns the {{_NAME}}
   2.191 ---	attribute of the specified object's class.
   2.192 +--	name = object:getClassName(): This function returns the {{_NAME}}
   2.193 +--	attribute of the specified class or object's class.
   2.194  -------------------------------------------------------------------------------
   2.195  
   2.196  function Class:getClassName()
   2.197 @@ -74,6 +169,24 @@
   2.198  end
   2.199  
   2.200  -------------------------------------------------------------------------------
   2.201 +--	is_descendant = object:checkDescend(class):
   2.202 +--	Returns '''true''' if {{object}} is an instance of a class descending
   2.203 +--	from the specified {{class}}. It is also possible to apply this function
   2.204 +--	to a class instead of an object, e.g.:
   2.205 +--			Class.checkDescend(Button, Area)
   2.206 +-------------------------------------------------------------------------------
   2.207 +
   2.208 +function Class:checkDescend(ancestor)
   2.209 +	while self ~= ancestor do
   2.210 +		self = getmetatable(self)
   2.211 +		if not self then
   2.212 +			return false
   2.213 +		end
   2.214 +	end
   2.215 +	return true
   2.216 +end
   2.217 +
   2.218 +-------------------------------------------------------------------------------
   2.219  --	make Class and its descendants functors:
   2.220  -------------------------------------------------------------------------------
   2.221  
     3.1 --- a/cgi-bin/tek/class/cgi/post.lua	Fri Sep 12 22:14:53 2008 +0200
     3.2 +++ b/cgi-bin/tek/class/cgi/post.lua	Sat Sep 13 15:57:41 2008 +0200
     3.3 @@ -14,11 +14,13 @@
     3.4  local min = math.min
     3.5  
     3.6  module("tek.class.cgi.post", tek.class)
     3.7 -_VERSION = "TEK CGI Post Class 1.3"
     3.8 +_VERSION = "Post 1.4"
     3.9 +local Post = _M
    3.10  
    3.11  -------------------------------------------------------------------------------
    3.12  -- Decode an URL-encoded string (see RFC 2396)
    3.13  -------------------------------------------------------------------------------
    3.14 +
    3.15  local function unescape (str)
    3.16  	str = str:gsub("+", " ")
    3.17  	str = str:gsub("%%(%x%x)", function(h)
    3.18 @@ -35,6 +37,7 @@
    3.19  -- Multi-valued names will be represented as tables with numerical indexes
    3.20  --	(in the order they came).
    3.21  -------------------------------------------------------------------------------
    3.22 +
    3.23  local function insertfield (args, name, value)
    3.24  	if not args[name] then
    3.25  		args[name] = value
    3.26 @@ -59,6 +62,7 @@
    3.27  --
    3.28  --  Each decoded (name=value) pair is inserted into table [[args]]
    3.29  -------------------------------------------------------------------------------
    3.30 +
    3.31  local function parsequery (query, args)
    3.32  	if type(query) == "string" then
    3.33  		local insertfield, unescape = insertfield, unescape
    3.34 @@ -69,8 +73,6 @@
    3.35  	end
    3.36  end
    3.37  
    3.38 --------------------------------------------------------------------------------
    3.39 -
    3.40  local function iterate (inp)
    3.41  	local current = ""
    3.42  	return function (del, out)
    3.43 @@ -101,10 +103,19 @@
    3.44  end
    3.45  
    3.46  -------------------------------------------------------------------------------
    3.47 +--	new: overrides
    3.48 +-------------------------------------------------------------------------------
    3.49  
    3.50 ---	POST parser
    3.51 -
    3.52 -local Post = _M
    3.53 +function Post.new(class, self)
    3.54 +	self = self or { }
    3.55 +	self.read = self.read or false
    3.56 +	self.readuntil = self.readuntil or false
    3.57 +	self.discardinput = self.discardinput or false
    3.58 +	self.content_type = false
    3.59 +	self.maxinput = self.maxinput or false
    3.60 +	self.maxfilesize = self.maxfilesize or false
    3.61 +	return Class.new(class, self)
    3.62 +end
    3.63  
    3.64  -------------------------------------------------------------------------------
    3.65  -- Read the headers of the next multipart/form-data field
    3.66 @@ -135,6 +146,7 @@
    3.67  -------------------------------------------------------------------------------
    3.68  -- Extract a field name (and possible filename) from its disposition header
    3.69  -------------------------------------------------------------------------------
    3.70 +
    3.71  function Post:getfieldnames (headers)
    3.72    local disposition_hdr = headers["content-disposition"]
    3.73    local attrs = {}
    3.74 @@ -152,6 +164,7 @@
    3.75  -------------------------------------------------------------------------------
    3.76  -- Read the contents of a 'regular' field to a string
    3.77  -------------------------------------------------------------------------------
    3.78 +
    3.79  function Post:readfieldcontents ()
    3.80  	local value = ""
    3.81  	local boundaryline = "\r\n"..self.boundary
    3.82 @@ -166,6 +179,7 @@
    3.83  -------------------------------------------------------------------------------
    3.84  -- Read the contents of a 'file' field to a temporary file (file upload)
    3.85  -------------------------------------------------------------------------------
    3.86 +
    3.87  function Post:fileupload (filename)
    3.88  	-- create a temporary file for uploading the file field
    3.89  	local file, err = tmpfile()
    3.90 @@ -197,6 +211,7 @@
    3.91  -------------------------------------------------------------------------------
    3.92  -- Compose a file field 'value'
    3.93  -------------------------------------------------------------------------------
    3.94 +
    3.95  function Post:filevalue (filehandle, filename, filesize, headers)
    3.96    -- the temporary file handle
    3.97    local value = { file = filehandle,
    3.98 @@ -233,6 +248,7 @@
    3.99  -- If the field is not of type 'file', [[value]] contains the field
   3.100  -- contents.
   3.101  -------------------------------------------------------------------------------
   3.102 +
   3.103  function Post:main (inputsize, args)
   3.104  
   3.105  	-- create a temporary file for processing input data
   3.106 @@ -279,6 +295,7 @@
   3.107  --   (defined by the metavariable CONTENT_LENGTH) exceeds the
   3.108  --   maximum input size allowed
   3.109  -------------------------------------------------------------------------------
   3.110 +
   3.111  function Post:parse(defs)
   3.112  	assert (type(defs.args) == "table", "field `args' must be a table")
   3.113  	assert (defs.read)
     4.1 --- a/cgi-bin/tek/class/cgi/request.lua	Fri Sep 12 22:14:53 2008 +0200
     4.2 +++ b/cgi-bin/tek/class/cgi/request.lua	Sat Sep 13 15:57:41 2008 +0200
     4.3 @@ -19,7 +19,7 @@
     4.4  local io = io
     4.5  
     4.6  module("tek.class.cgi.request", tek.class)
     4.7 -_VERSION = "TEK CGI Request Class 5.4"
     4.8 +_VERSION = "Request 5.5"
     4.9  
    4.10  -------------------------------------------------------------------------------
    4.11  --	Request class:
    4.12 @@ -28,14 +28,13 @@
    4.13  local Request = _M
    4.14  
    4.15  function Request.new(class, self)
    4.16 -
    4.17 -	self = Class.new(class, self or { })
    4.18 -
    4.19 +	self = self or { }
    4.20 +	self.args = false
    4.21 +	self.document = false
    4.22  	self.maxinput = self.maxinput or 1048575
    4.23  	self.maxfilesize = self.maxfilesize or 524288
    4.24  	self.getenv = self.getenv or getenv
    4.25  	self.read = self.read or read
    4.26 -
    4.27  	self.CONTENT_TYPE = self.getenv("CONTENT_TYPE")
    4.28  	self.CONTENT_LENGTH = tonumber(self.getenv("CONTENT_LENGTH"))
    4.29  	self.PATH_TRANSLATED = self.getenv("PATH_TRANSLATED")
    4.30 @@ -45,10 +44,8 @@
    4.31  	self.UNIQUE_ID = self.getenv("UNIQUE_ID")
    4.32  	self.REQUEST_URI = self.getenv("REQUEST_URI")
    4.33  	self.SCRIPT_FILENAME = self.getenv("SCRIPT_FILENAME")
    4.34 -	self.PATH_INFO = getenv("PATH_INFO")
    4.35 -
    4.36 -	return self
    4.37 -
    4.38 +	self.PATH_INFO = self.PATH_INFO or getenv("PATH_INFO") or false
    4.39 +	return Class.new(class, self)
    4.40  end
    4.41  
    4.42  -------------------------------------------------------------------------------
     5.1 --- a/cgi-bin/tek/class/fastcgi.lua	Fri Sep 12 22:14:53 2008 +0200
     5.2 +++ b/cgi-bin/tek/class/fastcgi.lua	Sat Sep 13 15:57:41 2008 +0200
     5.3 @@ -32,18 +32,18 @@
     5.4  local min = math.min
     5.5  
     5.6  module("tek.class.fastcgi", tek.class)
     5.7 -_VERSION = "FastCGI 0.5"
     5.8 +_VERSION = "FastCGI 0.6"
     5.9  
    5.10  -------------------------------------------------------------------------------
    5.11  -- local FIFO class:
    5.12  -------------------------------------------------------------------------------
    5.13  
    5.14 -local FIFO = Class:newClass()
    5.15 +local FIFO = Class:newClass { _NAME = "_fcgi_fifo" }
    5.16  
    5.17  function FIFO.new(class, self)
    5.18 -	self = Class.new(class, self or { })
    5.19 +	self = self or { }
    5.20  	self.buf = self.buf or { }
    5.21 -	return self
    5.22 +	return Class.new(class, self)
    5.23  end
    5.24  
    5.25  function FIFO:write(s)
    5.26 @@ -179,9 +179,11 @@
    5.27  local FastCGI = _M
    5.28  
    5.29  function FastCGI.new(class, self)
    5.30 -	self = Class.new(class, self)
    5.31 +	self = self or { }
    5.32  	self.requests = { }
    5.33 -	return self
    5.34 +	self.socket = false
    5.35 +	self.serving = false
    5.36 +	return Class.new(class, self)
    5.37  end
    5.38  
    5.39  function FastCGI:readrecord()
    5.40 @@ -351,13 +353,9 @@
    5.41  	elseif r.type == self.FCGI_STDIN or r.type == self.FCGI_DATA then
    5.42  		local s, fin = self:collectstream(r)
    5.43  		if fin then
    5.44 -			if self.have_stream then
    5.45 -				return self:have_stream(req, r.type, s)
    5.46 -			end
    5.47 +			return self:have_stream(req, r.type, s)
    5.48  		else
    5.49 -			if self.update_stream then
    5.50 -				return self:update_stream(req, r.type, s)
    5.51 -			end
    5.52 +			return self:update_stream(req, r.type, s)
    5.53  		end
    5.54  
    5.55  	else
    5.56 @@ -377,8 +375,8 @@
    5.57  function FastCGI:serve(socket)
    5.58  	assert(socket)
    5.59  	self.socket = socket
    5.60 -	self.serve = true
    5.61 -	while self.serve do
    5.62 +	self.serving = true
    5.63 +	while self.serving do
    5.64  		local r = self:readrecord()
    5.65  		if not r then
    5.66  			break
    5.67 @@ -395,7 +393,7 @@
    5.68  -------------------------------------------------------------------------------
    5.69  
    5.70  function FastCGI:stop()
    5.71 -	self.serve = false
    5.72 +	self.serving = false
    5.73  end
    5.74  
    5.75  -------------------------------------------------------------------------------
    5.76 @@ -418,3 +416,11 @@
    5.77  --	This method must be implemented by the user before anything useful can be
    5.78  --	done with a FastCGI request.
    5.79  -------------------------------------------------------------------------------
    5.80 +
    5.81 +function FastCGI:have_params()
    5.82 +	return true
    5.83 +end
    5.84 +
    5.85 +function FastCGI:update_stream()
    5.86 +	return true
    5.87 +end
     6.1 --- a/cgi-bin/tek/class/loona.lua	Fri Sep 12 22:14:53 2008 +0200
     6.2 +++ b/cgi-bin/tek/class/loona.lua	Sat Sep 13 15:57:41 2008 +0200
     6.3 @@ -37,7 +37,7 @@
     6.4  -------------------------------------------------------------------------------
     6.5  
     6.6  module("tek.class.loona", tek.class)
     6.7 -_VERSION = "LOona Class 5.3"
     6.8 +_VERSION = "LOona Class 5.4"
     6.9  
    6.10  -------------------------------------------------------------------------------
    6.11  --	Markup:
    6.12 @@ -89,11 +89,10 @@
    6.13  --	class Session:
    6.14  -------------------------------------------------------------------------------
    6.15  
    6.16 -local Session = Class:newClass()
    6.17 +local Session = Class:newClass { _NAME = "_session" }
    6.18  
    6.19  function Session.new(class, self)
    6.20 -
    6.21 -	self = Class.new(class, self or { })
    6.22 +	self = self or { }
    6.23  
    6.24  	assert(self.id, "No session Id")
    6.25   	assert(self.sessiondir, "No session directory")
    6.26 @@ -101,13 +100,15 @@
    6.27  	self.name = self.id:gsub("(.)", function(a)
    6.28  		return ("%02x"):format(a:byte())
    6.29  	end)
    6.30 +
    6.31  	self.filename = self.sessiondir .. "/" .. self.name
    6.32  	-- remove non-dotted files (expired sessions) from sessions dir:
    6.33 +
    6.34  	util.expire(self.sessiondir, "[^.]%S+", self.maxage or 600)
    6.35  	-- load session state:
    6.36  	self.data = lib.source(self.filename) or { }
    6.37  
    6.38 -	return self
    6.39 +	return Class.new(class, self)
    6.40  end
    6.41  
    6.42  function Session:save()
    6.43 @@ -346,7 +347,7 @@
    6.44  			table.insert(tab, { entries = sectionpath.subs })
    6.45  		end
    6.46  	end
    6.47 -	return tab, sectionpath
    6.48 +	return tab, sectionpath or false
    6.49  end
    6.50  
    6.51  
    6.52 @@ -1472,7 +1473,7 @@
    6.53  				self:dbmsg("Cannot delete published profile", c))
    6.54  			if self.args.actionconfirm then
    6.55  				self:deleteprofile(c)
    6.56 -				self.profile = nil
    6.57 +				self.profile = false
    6.58  				self.args.profile = nil
    6.59  				self:init()
    6.60  				save = true
    6.61 @@ -1512,7 +1513,7 @@
    6.62  			-- Publish profile
    6.63  
    6.64  			local c = self:checkprofilename(self.args.publishprofile:lower())
    6.65 -			if c ~= self.publicprofile then
    6.66 +			if c ~= self.pubprofile then
    6.67  				if self.args.actionconfirm then
    6.68  					self:publishprofile(c)
    6.69  					save = true
    6.70 @@ -1601,20 +1602,45 @@
    6.71  end
    6.72  
    6.73  
    6.74 +local function wrout(self, s)
    6.75 +	self.buf:out(s)
    6.76 +end
    6.77 +
    6.78 +
    6.79 +local function headout(self, s)
    6.80 +	self.buf:addheader(s)
    6.81 +end
    6.82 +
    6.83 +
    6.84  function Loona.new(class, self)
    6.85  
    6.86 -	self = Class.new(class, self or { })
    6.87 -
    6.88  	local parsed, msg
    6.89  
    6.90 +	self = self or { }
    6.91 +
    6.92 +	self.langs = false
    6.93 +	self.document = false
    6.94 +	self.profile = false
    6.95 +	self.pubprofile = false
    6.96 +	self.profile = false
    6.97 +	self.lang = false
    6.98 +	self.ispubprofile = false
    6.99 +	self.contentdir = false
   6.100 +	self.indexfname = false
   6.101 +	self.sections = false
   6.102 +	self.section = false
   6.103 +	self.submenus = false
   6.104 +	self.sectionpath = false
   6.105 +	self.sectionname = false
   6.106 +	self.getdocname = false
   6.107 +	self.useralert = false
   6.108 +	self.loginfailed = false
   6.109 +
   6.110  	-- Buffer
   6.111  
   6.112 -	self.out = self.out or function(self, s)
   6.113 -		self.buf:out(s)
   6.114 -	end
   6.115 -	self.addheader = self.addheader or function(self, s)
   6.116 -		self.buf:addheader(s)
   6.117 -	end
   6.118 +	self.out = self.out or wrout
   6.119 +	self.addheader = self.addheader or headout
   6.120 +
   6.121  
   6.122  	-- Get configuration
   6.123  
   6.124 @@ -1654,6 +1680,7 @@
   6.125  	end
   6.126  	setmetatable(self.locale, locmt)
   6.127  
   6.128 +
   6.129  	-- Get request, args, document, script name, request path
   6.130  
   6.131  	self.request = self.request or Request:new()
   6.132 @@ -1662,10 +1689,14 @@
   6.133  
   6.134  	self.requesthandler = self.requesthandler or self.cgi_document.Handler
   6.135   	self.requestdocument = self.requestdocument or self.cgi_document.Name
   6.136 -	self.requestpath = self.requestpath or self.cgi_document.VirtualPath
   6.137 -	self.explicitlang = not self.requestlang and self.args.lang
   6.138 +	self.requestpath = self.requestpath or self.cgi_document.VirtualPath or false
   6.139 +	self.requestlang = self.requestlang or false
   6.140 +	self.explicitlang = not self.requestlang and self.args.lang or false
   6.141  	self.secure = not self.insecure and (self.request.SERVER_PORT == self.config.secureport)
   6.142  
   6.143 +	self.nologin = self.nologin or false
   6.144 +	self.authuser = false
   6.145 +
   6.146  	-- Manage login and establish session
   6.147  
   6.148  	if not self.nologin then
   6.149 @@ -1680,18 +1711,18 @@
   6.150  			self.args.session = sid -- !
   6.151  			if self.args.login == "false" then
   6.152  				self.session:delete()
   6.153 -				self.session = nil
   6.154 +				self.session = false
   6.155  			elseif self.args.password then
   6.156  				self.loginfailed = true
   6.157  				local match, username, perm, profile =
   6.158 -					self:checkpw(self.args.login, self.args.password)
   6.159 +					checkpw(self, self.args.login, self.args.password)
   6.160  				if match then
   6.161  					self.session.data.authuser = self.args.login
   6.162  					self.session.data.username = username
   6.163  					self.session.data.permissions = perm
   6.164  					self.session.data.profile = profile
   6.165  					self.session.data.id = self.session.id
   6.166 -					self.loginfailed = nil
   6.167 +					self.loginfailed = false
   6.168  				end
   6.169  			end
   6.170  		end
   6.171 @@ -1699,9 +1730,16 @@
   6.172  	end
   6.173  
   6.174  	if self.nologin or not self.authuser then
   6.175 -		self.authuser = nil
   6.176 -		self.session = nil
   6.177 -		self.args.session = nil
   6.178 +		self.authuser = false
   6.179 +		self.session = false
   6.180 +		self.args.session = false
   6.181 +		self.authuser_edit = false
   6.182 +		self.authuser_menu = false
   6.183 +		self.authuser_publish = false
   6.184 +		self.authuser_profile = false
   6.185 +		self.authuser_visible = false
   6.186 +		self.authuser_debug = false
   6.187 +		self.authuser_seeall = false
   6.188  	else
   6.189  		self.authuser_edit = self.session.data.permissions:find("e") and true
   6.190  		self.authuser_menu = self.session.data.permissions:find("m") and true
   6.191 @@ -1713,6 +1751,7 @@
   6.192  		self.authuser_seeall = self.session.data.permissions:find("a") and true
   6.193  	end
   6.194  
   6.195 +	self = Class.new(class, self)
   6.196  
   6.197  	-- Get lang, locale, profile, section
   6.198  
   6.199 @@ -1724,34 +1763,14 @@
   6.200  		self.args.profile = nil
   6.201  	end
   6.202  
   6.203 -
   6.204  	-- Current document
   6.205  
   6.206  	self.document = self.requestdocument .. "/" .. self.sectionpath
   6.207 +	assert(self.document ~= nil)
   6.208  	if self.authuser then
   6.209 -		self.getdocname = function(self, path)
   6.210 -			local url, anch = path:match("^([^#]*)(#?.*)$")
   6.211 -			path = url ~= "" and url
   6.212 -			anch = anch or ""
   6.213 -			return self.requestdocument .. "/" .. (path or self.sectionpath) .. anch
   6.214 -		end
   6.215 +		self.getdocname = getDocNameNoAuth
   6.216  	else
   6.217 -		self.getdocname = function(self, path, haveargs)
   6.218 -			local url, anch = path:match("^([^#]*)(#?.*)$")
   6.219 -			path = url ~= "" and url
   6.220 -			anch = anch or ""
   6.221 -			local dyn, exists
   6.222 -			dyn, path, exists = self:isdynamic(path or self.sectionpath)
   6.223 -			if dyn or haveargs or not exists then
   6.224 -				return self.requestdocument .. "/" .. path .. anch
   6.225 -			end
   6.226 -			path = path == self.config.defname and "index" or path
   6.227 -
   6.228 -			if path:match("%.html$") then
   6.229 -				return "/" .. path:gsub("/", "_") .. anch
   6.230 -			end
   6.231 -			return "/" .. path:gsub("/", "_") .. ".html" .. anch
   6.232 -		end
   6.233 +		self.getdocname = getDocNameAuth
   6.234  	end
   6.235  
   6.236  	-- Save session state
   6.237 @@ -1764,12 +1783,40 @@
   6.238  end
   6.239  
   6.240  
   6.241 -function Loona:checkpw(login, passwd)
   6.242 +function Loona:getDocNameNoAuth(path)
   6.243 +	local url, anch = path:match("^([^#]*)(#?.*)$")
   6.244 +	path = url ~= "" and url
   6.245 +	anch = anch or ""
   6.246 +	return self.requestdocument .. "/" .. (path or self.sectionpath) .. anch
   6.247 +end
   6.248 +
   6.249 +
   6.250 +function Loona:getDocNameAuth(path, haveargs)
   6.251 +	local url, anch = path:match("^([^#]*)(#?.*)$")
   6.252 +	path = url ~= "" and url
   6.253 +	anch = anch or ""
   6.254 +	local dyn, exists
   6.255 +	dyn, path, exists = self:isdynamic(path or self.sectionpath)
   6.256 +	if dyn or haveargs or not exists then
   6.257 +		return self.requestdocument .. "/" .. path .. anch
   6.258 +	end
   6.259 +	path = path == self.config.defname and "index" or path
   6.260 +
   6.261 +	if path:match("%.html$") then
   6.262 +		return "/" .. path:gsub("/", "_") .. anch
   6.263 +	end
   6.264 +	return "/" .. path:gsub("/", "_") .. ".html" .. anch
   6.265 +end
   6.266 +
   6.267 +
   6.268 +function Loona.checkpw(self, login, passwd)
   6.269  	local pwddb = lib.source(self.config.passwdfile)
   6.270 -	local pwdent = pwddb[login]
   6.271 -	if pwdent and pwdent.password == passwd then
   6.272 -		return true, pwdent.username or login,
   6.273 -			pwdent.permissions or "", pwdent.profile
   6.274 +	if pwddb then
   6.275 +		local pwdent = pwddb[login]
   6.276 +		if pwdent and pwdent.password == passwd then
   6.277 +			return true, pwdent.username or login,
   6.278 +				pwdent.permissions or "", pwdent.profile
   6.279 +		end
   6.280  	end
   6.281  end
   6.282  
     7.1 --- a/cgi-bin/tek/class/loona/buffer.lua	Fri Sep 12 22:14:53 2008 +0200
     7.2 +++ b/cgi-bin/tek/class/loona/buffer.lua	Sat Sep 13 15:57:41 2008 +0200
     7.3 @@ -10,7 +10,7 @@
     7.4  local unpack, insert, stdout = unpack, table.insert, io.stdout
     7.5  
     7.6  module("tek.class.loona.buffer", tek.class)
     7.7 -_VERSION = "LOona Buffer Class 2.2"
     7.8 +_VERSION = "LOona Buffer 2.3"
     7.9  
    7.10  -------------------------------------------------------------------------------
    7.11  --	Buffer class:
    7.12 @@ -19,10 +19,10 @@
    7.13  local Buffer = _M
    7.14  
    7.15  function Buffer.new(class, self)
    7.16 -	self = Class.new(class, self or { })
    7.17 +	self = self or { }
    7.18  	self.outbuf = self.outbuf or { }
    7.19  	self.headerbuf = self.headerbuf or { }
    7.20 -	return self
    7.21 +	return Class.new(class, self)
    7.22  end
    7.23  
    7.24  -------------------------------------------------------------------------------