aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthe lemons <citrons@mondecitronne.com>2022-03-01 16:21:14 -0600
committerthe lemons <citrons@mondecitronne.com>2022-03-01 16:21:14 -0600
commit1d2e81782afb3addad4d7a47cc8a906006e1370b (patch)
tree1ce4852cf27fab48682e1f81f0eedbe841a44a77
parent4642ea47cfb0e2e106c184fc31fa96c88826e572 (diff)
parente2fb3fe657b594007be1e53037688adb8baa20eb (diff)
Merge branch 'heavoids'
-rwxr-xr-xzzcxz.cgi89
1 files changed, 77 insertions, 12 deletions
diff --git a/zzcxz.cgi b/zzcxz.cgi
index c9a71d5..72bdee5 100755
--- a/zzcxz.cgi
+++ b/zzcxz.cgi
@@ -49,6 +49,7 @@ local function parse_qs(str,sep)
local values = {}
for key,val in str:gmatch(string.format('([^%q=]+)(=*[^%q=]*)', sep, sep)) do
local key = decode(key)
+
local keys = {}
key = key:gsub('%[([^%]]*)%]', function(v)
-- extract keys between balanced brackets
@@ -100,6 +101,13 @@ if cookies.history then
table.insert(history, page)
end
end
+local flags = {}
+for k,v in pairs(cookies) do
+ local flag = k:match "flag_(.+)"
+ if flag then
+ flags[flag] = v
+ end
+end
local function redirect(to)
return "", {
@@ -150,7 +158,8 @@ local not_found = function()
}, { status = '404 not found' }
end
-local function parse_directive(line, directives)
+local function parse_directive(line, directives, tmp_flags)
+ flags = flags or {}
local directive, args = line:match "^#([A-Za-z]+)%s*(.-)\n?$"
directive = directive and directive:lower()
if not directive then
@@ -159,6 +168,25 @@ local function parse_directive(line, directives)
local redirect = args:match "^%s*(%w%w%w%w%w)%s*$"
if not redirect then return end
directives.redirect = redirect
+ elseif directive == "set" then
+ if args:match "^%s*$" then return end
+ local flagname, text = args:match "^%s*(%w+)%s*(.-)%s*$"
+ if not flagname then return end
+ text = text or ""
+ if utf8.len(flagname) > 150 or utf8.len(text) > 1000 then
+ return
+ end
+ directives.flags_updated[flagname] = text
+ tmp_flags[flagname] = text
+ elseif directive == "unset" then
+ local flagname = args:match "^%s*(%w+)%s*$"
+ if not flagname then return end
+ directives.flags_updated[flagname] = false
+ tmp_flags[flagname] = nil
+ elseif directive == "require" then
+ local flagname = args:match "^%s*(%w+)%s*$"
+ if not flagname then return end
+ directives.require[flagname] = true
else
return
end
@@ -168,7 +196,11 @@ end
local load_page
local function convert_markup(m)
local result = {}
- local directives = {}
+ local tmp_flags = {}
+ for name, value in pairs(flags) do
+ tmp_flags[name] = value
+ end
+ local directives = {flags_updated = {}, require = {}}
local code_block = false
for line in (m..'\n'):gmatch "(.-)\n" do
if not code_block then
@@ -176,7 +208,7 @@ local function convert_markup(m)
goto continue
end
if line:sub(1,1) == '#' and
- parse_directive(line, directives) then
+ parse_directive(line, directives, tmp_flags) then
if directives.redirect then
local to = load_page(directives.redirect)
if to then
@@ -227,7 +259,15 @@ local function convert_markup(m)
return table.concat(result), directives
end
-
+local function target_requirements(p)
+ local page = load_page(p, false, true)
+ if not page then return true end
+ local _,directives = convert_markup(page.content)
+ for k,v in pairs(directives.require) do
+ if not flags[k] then return false end
+ end
+ return true
+end
local function parse_page(s)
local page = {}
page.title = s:match "^(.-)\n"
@@ -269,7 +309,8 @@ local function new_action(page, action, result)
::generate_name::
local new_name = {}
for i=1,5 do
- table.insert(new_name, string.char(string.byte 'a' + math.random(0,25)))
+ table.insert(new_name, string.char(
+ string.byte 'a' + math.random(0,25)))
end
new_name = table.concat(new_name)
@@ -367,9 +408,11 @@ map["^/g/(%w%w%w%w%w)$"] = function(p)
local actions = {}
for _,a in ipairs(page.actions) do
- table.insert(actions,
- ('<li><a href="%s">%s</a></li>'):format(
- html_encode(a.target), html_encode(a.action)))
+ if target_requirements(a.target) then
+ table.insert(actions,
+ ('<li><a href="%s">%s</a></li>'):format(
+ html_encode(a.target), html_encode(a.action)))
+ end
end
if not directives.deadend then
table.insert(actions,
@@ -395,8 +438,23 @@ map["^/g/(%w%w%w%w%w)$"] = function(p)
-- ]]):format(p)
end
- local hist_cookie = ('history=%s; path=/; secure; max-age=99999999999')
- :format(table.concat(history, ',')..',')
+ local cookies = {}
+ table.insert(cookies,
+ ('history=%s; path=/; secure; max-age=99999999999')
+ :format(table.concat(history, ',')..','))
+
+ for flagname, text in pairs(directives.flags_updated) do
+ if text then
+ table.insert(cookies,
+ ('flag_%s=%s; secure; max-age=999999999999')
+ :format(flagname, url_encode(text)))
+ else
+ -- clear the cookie by expiring it in the past
+ table.insert(cookies,
+ ('flag_%s=; expires=Thu, 01 Jan 1970 00:00:00 GMT;')
+ :format(flagname))
+ end
+ end
return base {
title = html_encode(title),
@@ -408,7 +466,7 @@ map["^/g/(%w%w%w%w%w)$"] = function(p)
drawthis = draw_this,
log = show_hist(),
},
- }, { headers = { ['set-cookie'] = hist_cookie } }
+ }, {headers = {["set-cookie"] = cookies, bees = "3.14"}}
else
if directives.deadend then
return base {
@@ -622,10 +680,17 @@ resp.content_type = resp.content_type or 'text/html'
resp.status = resp.status or '200 OK'
resp.headers = resp.headers or {}
resp.headers['content-type'] = resp.content_type
+resp.headers['apioforms'] = math.random(0,104942)/2
print("status: "..resp.status)
for k,v in pairs(resp.headers) do
- print(("%s: %s"):format(k, v))
+ if type(v) == "table" then
+ for _, v2 in ipairs(v) do
+ print(("%s: %s"):format(k, v2))
+ end
+ else
+ print(("%s: %s"):format(k, v))
+ end
end
print ""