1.1 --- a/Makefile Wed Oct 10 10:53:15 2007 +0200
1.2 +++ b/Makefile Fri Nov 23 01:46:43 2007 +0100
1.3 @@ -1,6 +1,6 @@
1.4
1.5 #
1.6 -# Loona Makefile
1.7 +# LOona Makefile
1.8 # Written by Timm S. Mueller <tmueller at neoscientists.org>
1.9 # See copyright notice in COPYRIGHT
1.10 #
1.11 @@ -68,7 +68,7 @@
1.12 chmod -R 664 *
1.13 chown -R :$(GROUP) *
1.14 find . -type d | xargs chmod ugo+x
1.15 - chmod ugo+x $(CGIDIR)/loona.cgi $(CGIDIR)/loona_fastcgi.lua
1.16 + chmod ugo+x $(CGIDIR)/loona.cgi $(CGIDIR)/loona_fastcgi.lua $(CGIDIR)/lua.cgi
1.17 chown -R $(WWWUSER) $(VARDIR)/sessions $(VARDIR)/htmlcache
1.18 chown -R $(WWWUSER) $(CONTENTDIR) $(HTDIR)
1.19 find . -name CVS -type d | xargs -r chmod g+rw
2.1 --- a/cgi-bin/loona_fastcgi.lua Wed Oct 10 10:53:15 2007 +0200
2.2 +++ b/cgi-bin/loona_fastcgi.lua Fri Nov 23 01:46:43 2007 +0100
2.3 @@ -17,9 +17,15 @@
2.4 -- constants and globals:
2.5 -------------------------------------------------------------------------------
2.6
2.7 --- set global debug level:
2.8 +-- Set global debug level:
2.9 db.level = 4
2.10
2.11 +-- Address to bind server to:
2.12 +local SERVERADDR = "127.0.0.1"
2.13 +
2.14 +-- Port to bind server to:
2.15 +local SERVERPORT = 20000
2.16 +
2.17 -- The script name we enforce:
2.18 local SCRIPTNAME = "/index.lua"
2.19
2.20 @@ -31,7 +37,7 @@
2.21 -- FCGI Buffer class:
2.22 -------------------------------------------------------------------------------
2.23
2.24 -local FCGIBuffer = Buffer:newclass()
2.25 +local FCGIBuffer = Buffer:newClass()
2.26
2.27 function FCGIBuffer:flush()
2.28 local fcgi = self.fcgi
2.29 @@ -49,7 +55,7 @@
2.30 -- FCGI Server class:
2.31 -------------------------------------------------------------------------------
2.32
2.33 -local FCGIServer = FCGI:newclass()
2.34 +local FCGIServer = FCGI:newClass()
2.35
2.36 function FCGIServer:runapp(req)
2.37 loona.main(self.buffer, self.request, self.document, self.userdata)
2.38 @@ -109,13 +115,15 @@
2.39 -- main:
2.40 -------------------------------------------------------------------------------
2.41
2.42 +db.info("Binding server to %s, port %d", SERVERADDR, SERVERPORT)
2.43 +
2.44 -- global application state:
2.45 local app = { }
2.46
2.47 -- create FastCGI listening socket:
2.48 app.server = socket.tcp()
2.49 app.server:setoption("reuseaddr", true)
2.50 -app.server:bind("127.0.0.1", 20000)
2.51 +app.server:bind(SERVERADDR, SERVERPORT)
2.52 app.server:listen(64)
2.53
2.54 -- run:
2.55 @@ -128,8 +136,11 @@
2.56 client:close()
2.57 local mem1 = collectgarbage("count")
2.58 collectgarbage("collect")
2.59 - local t = socket.gettime() - t0
2.60 - db.info("Mem used: %.1fk - for request: %.1fk - elapsed: %.2fs",
2.61 + local t1 = socket.gettime()
2.62 + local t = t1 - t0
2.63 + local d = os.date("*t", t1)
2.64 + db.info("%04d-%02d-%02d %02d:%02d:%02d - Mem used: %.1fk - for request: %.1fk - elapsed: %.2fs",
2.65 + d.year, d.month, d.day, d.hour, d.min, d.sec,
2.66 mem1, mem1 - mem0, t)
2.67 end
2.68 end
3.1 --- a/cgi-bin/lua.cgi Wed Oct 10 10:53:15 2007 +0200
3.2 +++ b/cgi-bin/lua.cgi Fri Nov 23 01:46:43 2007 +0100
3.3 @@ -1,5 +1,6 @@
3.4 #!/usr/local/bin/lua
3.5 --
3.6 --- Mini CGI wrapper
3.7 +-- Mini CGI wrapper -
3.8 +-- Executes the addressed Lua script
3.9 --
3.10 dofile(os.getenv("PATH_TRANSLATED"))
4.1 --- a/cgi-bin/tek/app/loona.lua Wed Oct 10 10:53:15 2007 +0200
4.2 +++ b/cgi-bin/tek/app/loona.lua Fri Nov 23 01:46:43 2007 +0100
4.3 @@ -13,10 +13,7 @@
4.4
4.5
4.6 module "tek.app.loona"
4.7 -
4.8 -
4.9 -_VERSION = 2
4.10 -_REVISION = 0
4.11 +_VERSION = "LOona main 2.0"
4.12
4.13
4.14 function main(buf, request, document, userdata)
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/cgi-bin/tek/class.lua Fri Nov 23 01:46:43 2007 +0100
5.3 @@ -0,0 +1,38 @@
5.4 +
5.5 +--
5.6 +-- tek.class - Implements inheritance
5.7 +-- Written by Timm S. Mueller <tmueller at neoscientists.org>
5.8 +-- See copyright notice in COPYRIGHT
5.9 +--
5.10 +
5.11 +local tostring = tostring
5.12 +local getmetatable = getmetatable
5.13 +local setmetatable = setmetatable
5.14 +
5.15 +module "tek.class"
5.16 +_VERSION = "TEK Class 2.0"
5.17 +
5.18 +__index = _M
5.19 +
5.20 +function new(class, self)
5.21 + return setmetatable(self or { }, class)
5.22 +end
5.23 +
5.24 +newClass = function(baseclass, class)
5.25 + class = class or { }
5.26 + class.__index = class
5.27 + class.__call = newClass
5.28 + class._NAME = class._NAME or baseclass._NAME ..
5.29 + tostring(class):gsub("^table: 0x(.*)$", ".%1")
5.30 + return setmetatable(class, baseclass)
5.31 +end
5.32 +
5.33 +__call = newClass
5.34 +
5.35 +getClass = getmetatable
5.36 +
5.37 +function getClassName(self)
5.38 + return self._NAME
5.39 +end
5.40 +
5.41 +setmetatable(_M, { __call = newClass })
6.1 --- a/cgi-bin/tek/class/atom.lua Wed Oct 10 10:53:15 2007 +0200
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,43 +0,0 @@
6.4 -
6.5 ---
6.6 --- tek.class.atom
6.7 --- Copyright (C) 2007, Schulze & Mueller GbR
6.8 --- Written by Timm S. Mueller <tmueller@schulze-mueller.de>
6.9 ---
6.10 -
6.11 -local tostring = tostring
6.12 -local setmetatable, getmetatable = setmetatable, getmetatable
6.13 -
6.14 -module "tek.class.atom"
6.15 -
6.16 -_VERSION = 1
6.17 -_REVISION = 0
6.18 -
6.19 --------------------------------------------------------------------------------
6.20 --- Class implementation:
6.21 --------------------------------------------------------------------------------
6.22 -
6.23 -local atom = _M
6.24 -
6.25 -__index = atom
6.26 -
6.27 -function atom.new(class, self)
6.28 - return setmetatable(self or { }, class)
6.29 -end
6.30 -
6.31 -function atom.newclass(baseclass, class)
6.32 - class = class or { }
6.33 - class.__index = class
6.34 - class._BASECLASS = baseclass
6.35 - class._NAME = class._NAME or baseclass._NAME ..
6.36 - tostring(class):gsub("^table: 0x(.*)$", ".%1")
6.37 - return setmetatable(class, baseclass)
6.38 -end
6.39 -
6.40 -function atom:getclass()
6.41 - return getmetatable(self)
6.42 -end
6.43 -
6.44 -function atom:getclassname()
6.45 - return self._NAME
6.46 -end
7.1 --- a/cgi-bin/tek/class/cgi.lua Wed Oct 10 10:53:15 2007 +0200
7.2 +++ b/cgi-bin/tek/class/cgi.lua Fri Nov 23 01:46:43 2007 +0100
7.3 @@ -10,14 +10,9 @@
7.4
7.5
7.6 module "tek.class.cgi"
7.7 +_VERSION = "CGI 1.2"
7.8
7.9
7.10 -_VERSION = 1
7.11 -_REVISION = 1
7.12 -
7.13 -
7.14 --------------------------------------------------------------------------------
7.15 -
7.16 -- Encode string to URL. Optionally specify a set of characters
7.17 -- which are left unmodified. Possible characters that may be excluded
7.18 -- from conversion are $&+,/:;=?@ .
7.19 @@ -25,7 +20,7 @@
7.20 function encodeurl(s, excl)
7.21 local matchset = "$&+,/:;=?@" -- reserved chars with special meaning
7.22 if excl == true then
7.23 - matchset = ""
7.24 + matchset = ""
7.25 elseif excl and type(excl) == "string" then
7.26 matchset = matchset:gsub("[" .. keep:gsub(".", "%%%1") .. "]", "")
7.27 end
8.1 --- a/cgi-bin/tek/class/cgi/post.lua Wed Oct 10 10:53:15 2007 +0200
8.2 +++ b/cgi-bin/tek/class/cgi/post.lua Fri Nov 23 01:46:43 2007 +0100
8.3 @@ -6,21 +6,15 @@
8.4 --
8.5
8.6
8.7 -local Atom = require "tek.class.atom"
8.8 -local getfenv, setmetatable = getfenv, setmetatable
8.9 +local Class = require "tek.class"
8.10 local char = string.char
8.11 local assert, error, tonumber, type = assert, error, tonumber, type
8.12 local insert, pairs = table.insert, pairs
8.13 local tmpfile = io.tmpfile
8.14 local min = math.min
8.15
8.16 -
8.17 -module "tek.class.cgi.post"
8.18 -
8.19 -
8.20 -_VERSION = 1
8.21 -_REVISION = 1
8.22 -
8.23 +module("tek.class.cgi.post", Class)
8.24 +_VERSION = "TEK CGI Post Class 1.2"
8.25
8.26 -------------------------------------------------------------------------------
8.27 -- Decode an URL-encoded string (see RFC 2396)
8.28 @@ -110,9 +104,7 @@
8.29
8.30 -- POST parser
8.31
8.32 -
8.33 -local Post = Atom:newclass(getfenv())
8.34 -
8.35 +local Post = _M
8.36
8.37 -------------------------------------------------------------------------------
8.38 -- Read the headers of the next multipart/form-data field
9.1 --- a/cgi-bin/tek/class/cgi/request.lua Wed Oct 10 10:53:15 2007 +0200
9.2 +++ b/cgi-bin/tek/class/cgi/request.lua Fri Nov 23 01:46:43 2007 +0100
9.3 @@ -8,31 +8,28 @@
9.4 -- is read from a stream
9.5 --
9.6
9.7 -local Atom = require "tek.class.atom"
9.8 +local Class = require "tek.class"
9.9 local cgi = require "tek.class.cgi"
9.10 local post = require "tek.class.cgi.post"
9.11
9.12 -local getfenv, setmetatable = getfenv, setmetatable
9.13 local getenv, tonumber = os.getenv, tonumber
9.14 local open, read = io.open, io.read
9.15 local pairs = pairs
9.16 local tostring = tostring
9.17 local io = io
9.18
9.19 -module "tek.class.cgi.request"
9.20 -
9.21 -_VERSION = 5
9.22 -_REVISION = 2
9.23 +module("tek.class.cgi.request", Class)
9.24 +_VERSION = "TEK CGI Request Class 5.3"
9.25
9.26 -------------------------------------------------------------------------------
9.27 -- Request class:
9.28 -------------------------------------------------------------------------------
9.29
9.30 -local Request = Atom:newclass(getfenv())
9.31 +local Request = _M
9.32
9.33 function Request.new(class, self)
9.34
9.35 - self = Atom.new(class, self or { })
9.36 + self = Class.new(class, self or { })
9.37
9.38 self.maxinput = self.maxinput or 1048575
9.39 self.maxfilesize = self.maxfilesize or 524288
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/cgi-bin/tek/class/fastcgi.lua Fri Nov 23 01:46:43 2007 +0100
10.3 @@ -0,0 +1,373 @@
10.4 +
10.5 +--
10.6 +-- tek.class.fastcgi
10.7 +-- Written by Timm S. Mueller <tmueller@neoscientists.org>
10.8 +--
10.9 +-- Lua FastCGI protocol implementation - specifically written for
10.10 +-- the "external" server configurations (via IP socket)
10.11 +--
10.12 +-- Methods that must be overwritten by the user:
10.13 +-- fcgi:have_params(req, params) -- all parameters transferred
10.14 +--
10.15 +-- Methods that can be overwritten by the user:
10.16 +-- fcgi:abort(req) -- request aborted by webserver
10.17 +-- fcgi:update_stream(req, type, stream) -- stream created/updated
10.18 +-- fcgi:have_stream(req, type, stream) -- stream completed
10.19 +--
10.20 +
10.21 +local Class = require "tek.class"
10.22 +local socket = require "socket"
10.23 +local bit = require "bit"
10.24 +
10.25 +local insert, remove, concat, pairs, ipairs, error, assert =
10.26 + table.insert, table.remove, table.concat, pairs, ipairs, error, assert
10.27 +local tonumber, setmetatable, unpack, type =
10.28 + tonumber, setmetatable, unpack, type
10.29 +local char = string.char
10.30 +local math = math
10.31 +
10.32 +module("tek.class.fastcgi", Class)
10.33 +_VERSION = "FastCGI 0.2"
10.34 +
10.35 +-------------------------------------------------------------------------------
10.36 +-- local FIFO class:
10.37 +-------------------------------------------------------------------------------
10.38 +
10.39 +local FIFO = Class:newClass()
10.40 +
10.41 +function FIFO.new(class, self)
10.42 + self = Class.new(class, self or { })
10.43 + self.buf = self.buf or { }
10.44 + return self
10.45 +end
10.46 +
10.47 +function FIFO:write(s)
10.48 + if s and s ~= -1 then
10.49 + insert(self.buf, s)
10.50 + elseif self.buf[#self.buf] ~= -1 then
10.51 + insert(self.buf, -1) -- EOF
10.52 + end
10.53 +end
10.54 +
10.55 +function FIFO:readn(len)
10.56 + local t, p, l = { }
10.57 + while len > 0 do
10.58 + p = remove(self.buf, 1)
10.59 + if not p then
10.60 + break -- no more data
10.61 + end
10.62 + if p == -1 then
10.63 + insert(self.buf, -1) -- push back EOF
10.64 + break -- end of stream, EOF in next turn
10.65 + end
10.66 + l = p:len()
10.67 + if l > len then -- break buffer fragment in two
10.68 + insert(t, p:sub(1, len))
10.69 + insert(self.buf, 1, p:sub(len + 1))
10.70 + break
10.71 + end
10.72 + insert(t, p)
10.73 + len = len - l
10.74 + end
10.75 + return concat(t)
10.76 +end
10.77 +
10.78 +function FIFO:reada()
10.79 + local last = remove(self.buf)
10.80 + if last ~= -1 then -- not EOF
10.81 + insert(self.buf, last) -- push back
10.82 + last = nil
10.83 + end
10.84 + local s = concat(self.buf)
10.85 + self.buf = { last }
10.86 + return s
10.87 +end
10.88 +
10.89 +function FIFO:read(...)
10.90 + if self.buf[1] == -1 then
10.91 + return -- EOF
10.92 + end
10.93 + local t, s = { }
10.94 + for _, what in ipairs(arg) do
10.95 + if what == "*a" then
10.96 + s = self:reada()
10.97 + elseif type(what) == "number" then
10.98 + s = self:readn(tonumber(what))
10.99 + else
10.100 + error("unknwon format")
10.101 + end
10.102 + insert(t, s)
10.103 + end
10.104 + return unpack(t)
10.105 +end
10.106 +
10.107 +-- FCGI encoded lengths and key/value pairs:
10.108 +
10.109 +function FIFO:readlen()
10.110 + local l = self:read(1)
10.111 + if not l then return end
10.112 + l = l:byte()
10.113 + if l < 128 then
10.114 + return l
10.115 + end
10.116 + local t = self:read(3)
10.117 + if not t then return end
10.118 + return (l % 128) * 16777216 + t:byte(1) * 65536 +
10.119 + t:byte(2) * 256 + t:byte(3)
10.120 +end
10.121 +
10.122 +function FIFO:readkeyvals()
10.123 + local t = { }
10.124 + local l1, l2, key, val
10.125 + while true do
10.126 + l1 = self:readlen()
10.127 + if not l1 then break end
10.128 + l2 = self:readlen()
10.129 + if not l2 then break end
10.130 + key = self:read(l1)
10.131 + val = self:read(l2)
10.132 + t[key] = val
10.133 + end
10.134 + return t
10.135 +end
10.136 +
10.137 +-------------------------------------------------------------------------------
10.138 +-- FCGI class:
10.139 +-------------------------------------------------------------------------------
10.140 +
10.141 +FCGI_BEGIN_REQUEST = 1
10.142 +FCGI_ABORT_REQUEST = 2
10.143 +FCGI_END_REQUEST = 3
10.144 +FCGI_PARAMS = 4
10.145 +FCGI_STDIN = 5
10.146 +FCGI_STDOUT = 6
10.147 +FCGI_STDERR = 7
10.148 +FCGI_DATA = 8
10.149 +FCGI_GET_VALUES = 9
10.150 +FCGI_GET_VALUES_RESULT = 10
10.151 +FCGI_UNKNOWN_TYPE = 11
10.152 +
10.153 +local FCGI_RESPONDER = 1
10.154 +local FCGI_REQUEST_COMPLETE = 0
10.155 +local FCGI_UNKNOWN_ROLE = 3
10.156 +
10.157 +local function encodelen(buf, l)
10.158 + if l > 127 then
10.159 + insert(buf, char(bit.rshift(bit.band(l, 0x7f000000), 24) + 128))
10.160 + insert(buf, char(bit.rshift(bit.band(l, 0x00ff0000), 16)))
10.161 + insert(buf, char(bit.rshift(bit.band(l, 0x0000ff00), 8)))
10.162 + end
10.163 + insert(buf, char(bit.band(l, 0xff)))
10.164 +end
10.165 +
10.166 +local function encodekeyvals(t)
10.167 + local buf = { }
10.168 + for key, val in pairs(t) do
10.169 + encodelen(buf, key:len())
10.170 + encodelen(buf, val:len())
10.171 + insert(buf, key)
10.172 + insert(buf, val)
10.173 + end
10.174 + return concat(buf)
10.175 +end
10.176 +
10.177 +-- local FCGI = Class:newClass(_M)
10.178 +local FCGI = _M
10.179 +
10.180 +function FCGI.new(class, self)
10.181 + self = Class.new(class, self or { })
10.182 + self.requests = { }
10.183 + return self
10.184 +end
10.185 +
10.186 +function FCGI:readrecord()
10.187 + local t, err = self.socket:receive(8)
10.188 + if not t then return end
10.189 + if err then error(err) end
10.190 + local r = {
10.191 + ver = t:byte(1),
10.192 + type = t:byte(2),
10.193 + id = t:byte(3) * 256 + t:byte(4),
10.194 + len = t:byte(5) * 256 + t:byte(6)
10.195 + }
10.196 + if r.len == 0 then
10.197 + r.content = ""
10.198 + else
10.199 + r.content, err = self.socket:receive(r.len)
10.200 + if not r.content then return end
10.201 + if err then error(err) end
10.202 + end
10.203 + local pad = t:byte(7)
10.204 + if pad > 0 then
10.205 + t, err = self.socket:receive(pad)
10.206 + if not t then return end
10.207 + if err then error(err) end
10.208 + end
10.209 + return r
10.210 +end
10.211 +
10.212 +function FCGI:write(type, id, s)
10.213 + local totlen = s:len()
10.214 + local totpos = 1
10.215 + while totlen > 0 do
10.216 + local len = math.min(totlen, 65535)
10.217 + local buf = concat {
10.218 + char(1), -- version
10.219 + char(type), -- type
10.220 + char(bit.rshift(id, 8)), -- id1
10.221 + char(id % 256), -- id0
10.222 + char(bit.rshift(len, 8)), -- len1
10.223 + char(len % 256), -- len0
10.224 + char(0), -- pad = 0
10.225 + char(0), -- reserved
10.226 + s:sub(totpos, totpos + len - 1) -- content
10.227 + }
10.228 + totpos = totpos + len
10.229 + totlen = totlen - len
10.230 +
10.231 + len = buf:len()
10.232 + local pos, res, err = 1
10.233 + while pos <= len do
10.234 + res, err = self.socket:send(buf, pos)
10.235 + if not res then
10.236 + return nil, err
10.237 + end
10.238 + pos = res + 1
10.239 + end
10.240 + end
10.241 + return true
10.242 +end
10.243 +
10.244 +function FCGI:write_stdout(id, s)
10.245 + return self:write(FCGI_STDOUT, id, s)
10.246 +end
10.247 +
10.248 +function FCGI:collectstream(r)
10.249 + local req = self.requests[r.id]
10.250 + local s = req.streams[r.type]
10.251 + if not s then
10.252 + s = FIFO:new()
10.253 + req.streams[r.type] = s
10.254 + end
10.255 + if r.len == 0 then
10.256 + s:write() -- append EOF
10.257 + return s, true -- finished
10.258 + end
10.259 + s:write(r.content)
10.260 + return s
10.261 +end
10.262 +
10.263 +function FCGI:endrequest(req, protstatus, appstatus)
10.264 + protstatus = protstatus or req.protstatus or FCGI_REQUEST_COMPLETE
10.265 + appstatus = appstatus or req.appstatus or 0
10.266 + self.requests[req.id] = nil -- delete request
10.267 + return self:write(FCGI_END_REQUEST, req.id, concat {
10.268 + char(bit.rshift(bit.band(appstatus, 0x7f000000), 24)),
10.269 + char(bit.rshift(bit.band(appstatus, 0x00ff0000), 16)),
10.270 + char(bit.rshift(bit.band(appstatus, 0x0000ff00), 8)),
10.271 + char(bit.band(appstatus, 0xff)),
10.272 + char(protstatus),
10.273 + char(0), char(0), char(0)
10.274 + })
10.275 +end
10.276 +
10.277 +function FCGI:newrequest(id, role, flags)
10.278 + assert(not self.requests[id])
10.279 + local req = { id = id, role = role, flags = flags, streams = { } }
10.280 + self.requests[id] = req
10.281 + return req
10.282 +end
10.283 +
10.284 +function FCGI:processrecord(r)
10.285 +
10.286 + local c = r.content
10.287 + local req = self.requests[r.id]
10.288 +
10.289 + if r.type == FCGI_BEGIN_REQUEST then
10.290 + assert(not req)
10.291 + local role = c:byte(1) * 256 + c:byte(2)
10.292 + if role == FCGI_RESPONDER then
10.293 + -- new request
10.294 + local flags = c:byte(3)
10.295 + req = self:newrequest(r.id, role, flags)
10.296 + return true -- continue
10.297 + end
10.298 + -- unknown role
10.299 + return self:endrequest(req, FCGI_UNKNOWN_ROLE)
10.300 + end
10.301 +
10.302 + if not req then -- request already closed
10.303 + return true -- continue
10.304 + end
10.305 +
10.306 + if r.type == FCGI_ABORT_REQUEST then
10.307 + return self:abortrequest(req)
10.308 +
10.309 + elseif r.type == FCGI_GET_VALUES then
10.310 + local s, fin = self:collectstream(r)
10.311 + if s and fin then
10.312 + local res = { }
10.313 + for k in pairs(s:readkeyvals()) do
10.314 + if k == "FCGI_MAX_CONNS" then
10.315 + res.FCGI_MAX_CONNS = "16"
10.316 + elseif k == "FCGI_MAX_REQS" then
10.317 + res.FCGI_MAX_CONNS = "32"
10.318 + elseif k == "FCGI_MAX_REQS" then
10.319 + res.FCGI_MAX_CONNS = "1"
10.320 + end
10.321 + end
10.322 + res = encodekeyvals(res)
10.323 + return self:write(FCGI_GET_VALUES_RESULT, 0, res)
10.324 + end
10.325 +
10.326 + elseif r.type == FCGI_PARAMS then
10.327 + local s, fin = self:collectstream(r)
10.328 + if s and fin then
10.329 + req.params = s:readkeyvals()
10.330 + return self:have_params(req, req.params)
10.331 + end
10.332 +
10.333 + elseif r.type == self.FCGI_STDIN or r.type == self.FCGI_DATA then
10.334 + local s, fin = self:collectstream(r)
10.335 + if fin then
10.336 + if self.have_stream then
10.337 + return self:have_stream(req, r.type, s)
10.338 + end
10.339 + else
10.340 + if self.update_stream then
10.341 + return self:update_stream(req, r.type, s)
10.342 + end
10.343 + end
10.344 +
10.345 + else
10.346 + -- unknown record
10.347 + local buf = char(r.type) .. char(0):rep(7)
10.348 + return self:write(FCGI_UNKNOWN_TYPE, 0, buf)
10.349 + end
10.350 +
10.351 + return true -- continue
10.352 +end
10.353 +
10.354 +function FCGI:serve(socket)
10.355 + assert(socket)
10.356 + self.socket = socket
10.357 + self.serve = true
10.358 + while self.serve do
10.359 + local r = self:readrecord()
10.360 + if not r then
10.361 + break
10.362 + end
10.363 + if not self:processrecord(r) then
10.364 + break
10.365 + end
10.366 + end
10.367 +end
10.368 +
10.369 +function FCGI:stop()
10.370 + self.serve = false
10.371 +end
10.372 +
10.373 +function FCGI:abortrequest(req)
10.374 + -- request aborted by webserver, confirm:
10.375 + return self:endrequest(req)
10.376 +end
11.1 --- a/cgi-bin/tek/class/loona.lua Wed Oct 10 10:53:15 2007 +0200
11.2 +++ b/cgi-bin/tek/class/loona.lua Fri Nov 23 01:46:43 2007 +0100
11.3 @@ -5,7 +5,7 @@
11.4 -- See copyright notice in COPYRIGHT
11.5 --
11.6
11.7 -local Atom = require "tek.class.atom"
11.8 +local Class = require "tek.class"
11.9 local lib = require "tek.lib"
11.10 local luahtml = require "tek.lib.luahtml"
11.11 local posix = require "tek.os.posix"
11.12 @@ -26,30 +26,28 @@
11.13 xpcall = xpcall
11.14 }
11.15
11.16 -local table, string, assert, unpack, ipairs, pairs, type, require =
11.17 - table, string, assert, unpack, ipairs, pairs, type, require
11.18 -local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv
11.19 +local table, string, assert, unpack, ipairs, pairs, type, require, setfenv =
11.20 + table, string, assert, unpack, ipairs, pairs, type, require, setfenv
11.21 local open, remove, rename, getenv, time, date =
11.22 io.open, os.remove, os.rename, os.getenv, os.time, os.date
11.23 +local setmetatable = setmetatable
11.24
11.25 -------------------------------------------------------------------------------
11.26 -- Module setup:
11.27 -------------------------------------------------------------------------------
11.28
11.29 -module "tek.class.loona"
11.30 -
11.31 -_VERSION = 4
11.32 -_REVISION = 4
11.33 +module("tek.class.loona", Class)
11.34 +_VERSION = "LOona Class 5.0"
11.35
11.36 -------------------------------------------------------------------------------
11.37 -- class Session:
11.38 -------------------------------------------------------------------------------
11.39
11.40 -local Session = Atom:newclass()
11.41 +local Session = Class:newClass()
11.42
11.43 function Session.new(class, self)
11.44
11.45 - self = Atom.new(class, self or { })
11.46 + self = Class.new(class, self or { })
11.47
11.48 assert(self.id, "No session Id")
11.49 assert(self.sessiondir, "No session directory")
11.50 @@ -83,7 +81,7 @@
11.51 -- class Loona
11.52 -------------------------------------------------------------------------------
11.53
11.54 -local Loona = Atom:newclass(getfenv())
11.55 +local Loona = _M
11.56
11.57
11.58 function Loona:dbmsg(msg, detail)
11.59 @@ -251,8 +249,20 @@
11.60
11.61
11.62 function Loona:indexsections()
11.63 + local userperm = self.session and self.session.data.permissions
11.64 + userperm = userperm and userperm ~= "" and "[" .. userperm .. "]"
11.65 self:recursesections(self.sections, function(self, s, e)
11.66 - e.notvalid = (not self.secure and e.secure) or
11.67 + local permitted = true
11.68 + local sectperm = e.permissions
11.69 + if sectperm and sectperm ~= "" then
11.70 + permitted = false
11.71 + if userperm then
11.72 + local num = sectperm:len()
11.73 + sectperm:gsub(userperm, function() num = num - 1 end)
11.74 + permitted = num == 0
11.75 + end
11.76 + end
11.77 + e.notvalid = not permitted or (not self.secure and e.secure) or
11.78 (not self.authuser_visible and e.secret) or nil
11.79 e.notvisible = e.notvalid or not self.authuser_visible and e.hidden or nil
11.80 s[e.name] = e
11.81 @@ -703,8 +713,8 @@
11.82 local contentdir = self.contentdir
11.83 local edit, show, hidden, extramsg, changed
11.84
11.85 - if self.authuser_edit or self.authuser_profile or self.authuser_modifyprofile or self_authuser_attr
11.86 - or self.authuser_menu then
11.87 + if self.authuser_edit or self.authuser_profile or
11.88 + self.authuser_modifyprofile or self.authuser_menu then
11.89
11.90 local hiddenvars = table.concat( {
11.91 self:hidden("lang", self.args.lang),
11.92 @@ -796,6 +806,14 @@
11.93 </tr>
11.94 <tr>
11.95 <td align="right">
11.96 + ]] .. self.locale.PERMISSIONS .. [[
11.97 + </td>
11.98 + <td>
11.99 + <input size="30" maxlength="50" name="editpermissions" />
11.100 + </td>
11.101 + </tr>
11.102 + <tr>
11.103 + <td align="right">
11.104 ]] .. self.locale.REDIRECT .. [[
11.105 </td>
11.106 <td>
11.107 @@ -810,7 +828,8 @@
11.108 <hr />
11.109 ]])
11.110
11.111 - elseif self.args.actioneditprops and editkey == "main" and self.authuser_attr then
11.112 + elseif self.args.actioneditprops and editkey == "main" and
11.113 + self.authuser_menu then
11.114 hidden = true
11.115 if self.ispubprofile then
11.116 self:out([[<h2><span class="warn">]] .. self.locale.WARNING_YOU_ARE_IN_PUBLISHED_PROFILE ..[[</span></h2>]])
11.117 @@ -864,6 +883,14 @@
11.118 </tr>
11.119 <tr>
11.120 <td align="right">
11.121 + ]] .. self.locale.PERMISSIONS .. [[
11.122 + </td>
11.123 + <td>
11.124 + <input size="30" maxlength="50" name="editpermissions" value="]] .. (self.section.permissions or "") .. [[" />
11.125 + </td>
11.126 + </tr>
11.127 + <tr>
11.128 + <td align="right">
11.129 ]] .. self.locale.REDIRECT .. [[
11.130 </td>
11.131 <td>
11.132 @@ -1084,7 +1111,7 @@
11.133 end)
11.134 end
11.135
11.136 - if self.authuser_profile or self.authuser_edit or self.authuser_menu or self.authuser_attr then
11.137 + if self.authuser_profile or self.authuser_edit or self.authuser_menu then
11.138 self:out([[
11.139 <hr />
11.140 <div class="edit">]])
11.141 @@ -1107,7 +1134,7 @@
11.142 if self.authuser_edit then
11.143 self:out('- ' .. self:uilink(self.sectionpath, "[" .. self.locale.EDIT .. "]", "actionedit=true", "editkey=" .. editkey) .. " ")
11.144 end
11.145 - if editkey == "main" and self.authuser_attr then
11.146 + if editkey == "main" and self.authuser_menu then
11.147 self:out('- ' .. self:uilink(self.sectionpath, "[" .. self.locale.PROPERTIES .. "]", "actioneditprops=true", "editkey=" .. editkey) .. " ")
11.148 end
11.149 if (fname == savename or not self.section.subs) and (self.authuser_edit and self.authuser_menu) then
11.150 @@ -1272,6 +1299,8 @@
11.151 self.args.edittitle or nil,
11.152 redirect = self.args.editredirect ~= "" and
11.153 self.args.editredirect or nil,
11.154 + permissions = self.args.editpermissions ~= "" and
11.155 + self.args.editpermissions or nil,
11.156 hidden = self.args.editvisibility and true,
11.157 secret = self.args.editsecrecy and true,
11.158 secure = self.args.editsecure and true,
11.159 @@ -1301,6 +1330,8 @@
11.160 self.args.edittitle or nil
11.161 self.section.redirect =
11.162 self.args.editredirect ~= "" and self.args.editredirect or nil
11.163 + self.section.permissions =
11.164 + self.args.editpermisisons ~= "" and self.args.editpermissions or nil
11.165 save = true
11.166
11.167 elseif self.args.actionup then
11.168 @@ -1523,7 +1554,7 @@
11.169
11.170 function Loona.new(class, self)
11.171
11.172 - self = Atom.new(class, self or { })
11.173 + self = Class.new(class, self or { })
11.174
11.175 local parsed, msg
11.176
11.177 @@ -1625,22 +1656,24 @@
11.178 else
11.179 self.authuser_edit = self.session.data.permissions:find("e") and true
11.180 self.authuser_menu = self.session.data.permissions:find("m") and true
11.181 - self.authuser_attr = self.session.data.permissions:find("a") and true
11.182 self.authuser_profile = self.session.data.permissions:find("p") and true
11.183 self.authuser_modifyprofile = self.session.data.permissions:find("c") and true
11.184 self.authuser_visible = self.session.data.permissions:find("v") and true
11.185 self.authuser_debug = self.session.data.permissions:find("d") and true
11.186 end
11.187
11.188 +
11.189 -- Get lang, locale, profile, section
11.190
11.191 self:init()
11.192 +
11.193 if self.authuser then -- TODO?
11.194 self:handlechanges()
11.195 else
11.196 self.args.profile = nil
11.197 end
11.198
11.199 +
11.200 -- Current document
11.201
11.202 self.document = self.requestdocument .. "/" .. self.sectionpath
12.1 --- a/cgi-bin/tek/class/loona/buffer.lua Wed Oct 10 10:53:15 2007 +0200
12.2 +++ b/cgi-bin/tek/class/loona/buffer.lua Fri Nov 23 01:46:43 2007 +0100
12.3 @@ -5,24 +5,21 @@
12.4 -- See copyright notice in COPYRIGHT
12.5 --
12.6
12.7 -local Atom = require "tek.class.atom"
12.8 +local Class = require "tek.class"
12.9
12.10 -local getfenv, setmetatable, unpack, insert, stdout =
12.11 - getfenv, setmetatable, unpack, table.insert, io.stdout
12.12 +local unpack, insert, stdout = unpack, table.insert, io.stdout
12.13
12.14 -module "tek.class.loona.buffer"
12.15 -
12.16 -_VERSION = 2
12.17 -_REVISION = 0
12.18 +module("tek.class.loona.buffer", Class)
12.19 +_VERSION = "LOona Buffer Class 2.1"
12.20
12.21 -------------------------------------------------------------------------------
12.22 -- Buffer class:
12.23 -------------------------------------------------------------------------------
12.24
12.25 -local Buffer = Atom:newclass(getfenv())
12.26 +local Buffer = _M
12.27
12.28 function Buffer.new(class, self)
12.29 - self = Atom.new(class, self or { })
12.30 + self = Class.new(class, self or { })
12.31 self.outbuf = self.outbuf or { }
12.32 self.headerbuf = self.headerbuf or { }
12.33 return self
13.1 --- a/cgi-bin/tek/class/loona/markup.lua Wed Oct 10 10:53:15 2007 +0200
13.2 +++ b/cgi-bin/tek/class/loona/markup.lua Fri Nov 23 01:46:43 2007 +0100
13.3 @@ -14,10 +14,7 @@
13.4
13.5
13.6 module "tek.class.loona.markup"
13.7 -
13.8 -
13.9 -_VERSION = 2
13.10 -_REVISION = 0
13.11 +_VERSION = "LOona markup parser 2.1"
13.12
13.13
13.14 -- iterate over lines in a string
14.1 --- a/cgi-bin/tek/class/loona/util.lua Wed Oct 10 10:53:15 2007 +0200
14.2 +++ b/cgi-bin/tek/class/loona/util.lua Fri Nov 23 01:46:43 2007 +0100
14.3 @@ -13,10 +13,7 @@
14.4
14.5
14.6 module "tek.class.loona.util"
14.7 -
14.8 -
14.9 -_VERSION = 4
14.10 -_REVISION = 0
14.11 +_VERSION = "LOona utilities 4.1"
14.12
14.13
14.14 -- Directory iterator
15.1 --- a/cgi-bin/tek/lib.lua Wed Oct 10 10:53:15 2007 +0200
15.2 +++ b/cgi-bin/tek/lib.lua Fri Nov 23 01:46:43 2007 +0100
15.3 @@ -12,10 +12,7 @@
15.4
15.5
15.6 module "tek.lib"
15.7 -
15.8 -
15.9 -_VERSION = 1
15.10 -_REVISION = 1
15.11 +_VERSION = "TEK library 1.2"
15.12
15.13
15.14 -------------------------------------------------------------------------------
15.15 @@ -135,7 +132,7 @@
15.16 serialize(val, sorted, indent + 1, outfunc, saved)
15.17 outfunc(is .. '},\n')
15.18 elseif t == "string" then
15.19 - outfunc('"' .. val:gsub('([%z\001-\031"])', function(c)
15.20 + outfunc('"' .. val:gsub('([%z\001-\031\092"])', function(c)
15.21 return ("\\%03d"):format(c:byte())
15.22 end) .. '",\n')
15.23 elseif t == "number" or t == "boolean" then
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/cgi-bin/tek/lib/debug.lua Fri Nov 23 01:46:43 2007 +0100
16.3 @@ -0,0 +1,54 @@
16.4 +
16.5 +--
16.6 +-- tek.lib.debug
16.7 +-- Written by Timm S. Mueller <tmueller at neoscientists.org>
16.8 +-- See copyright notice in COPYRIGHT
16.9 +--
16.10 +
16.11 +local getinfo = require "debug".getinfo
16.12 +local date = require "os".date
16.13 +local stderr = require "io".stderr
16.14 +local tostring = tostring
16.15 +local ipairs = ipairs
16.16 +local type = type
16.17 +local unpack = unpack
16.18 +
16.19 +module "tek.lib.debug"
16.20 +
16.21 +level = 10 -- global default
16.22 +
16.23 +function print(lvl, msg, ...)
16.24 + if level and lvl >= level then
16.25 + local t = getinfo(3, "lS")
16.26 + local arg = { }
16.27 + for i, v in ipairs { ... } do
16.28 + arg[i] = type(v) == "table" and tostring(v) or v
16.29 + end
16.30 + stderr:write(("(%02d %s:%d) %s\n"):format(lvl,
16.31 + t.short_src, t.currentline, msg:format(unpack(arg))))
16.32 + end
16.33 +end
16.34 +
16.35 +function debug(msg, ...)
16.36 + print(1, msg, ...)
16.37 +end
16.38 +
16.39 +function trace(msg, ...)
16.40 + print(2, msg, ...)
16.41 +end
16.42 +
16.43 +function info(msg, ...)
16.44 + print(4, msg, ...)
16.45 +end
16.46 +
16.47 +function warn(msg, ...)
16.48 + print(5, msg, ...)
16.49 +end
16.50 +
16.51 +function error(msg, ...)
16.52 + print(10, msg, ...)
16.53 +end
16.54 +
16.55 +function fail(msg, ...)
16.56 + print(20, msg, ...)
16.57 +end
17.1 --- a/etc/passwd.lua.sample Wed Oct 10 10:53:15 2007 +0200
17.2 +++ b/etc/passwd.lua.sample Fri Nov 23 01:46:43 2007 +0100
17.3 @@ -14,6 +14,6 @@
17.4 --
17.5 -------------------------------------------------------------------------------
17.6
17.7 --- admin = { username = "admin", password = "blafasel", permissions = "emapcvd" }
17.8 --- foo = { username = "foo", password = "bar", permisisons = "vd" },
17.9 +-- admin = { username = "admin", password = "blafasel", permissions = "emapcvd" };
17.10 +-- foo = { username = "foo", password = "bar", permisisons = "vd" };
17.11
18.1 --- a/htdocs/index.lua Wed Oct 10 10:53:15 2007 +0200
18.2 +++ b/htdocs/index.lua Fri Nov 23 01:46:43 2007 +0100
18.3 @@ -56,7 +56,6 @@
18.4 </div>
18.5 <%if loona.authuser then%>
18.6 <div id="debug">
18.7 - Page took <%=os.clock()%>s to generate<br />
18.8 <a href="http://validator.w3.org/check?uri=referer"><img
18.9 src="http://www.w3.org/Icons/valid-xhtml10"
18.10 alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>