Overview
| Comment: | enable webfinger |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
64ae6724c26d73c349c71d534d955bb9 |
| User & Date: | lexi on 2021-01-24 23:18:29 |
| Other Links: | manifest | tags |
Context
|
2021-01-25
| ||
| 12:40 | first steps towards litepub support check-in: 26937ca853 user: lexi tags: trunk | |
|
2021-01-24
| ||
| 23:18 | enable webfinger check-in: 64ae6724c2 user: lexi tags: trunk | |
|
2021-01-22
| ||
| 17:22 | improve compose icon check-in: db0e155b9d user: lexi tags: trunk | |
Changes
Modified common.lua from [c868f8cd22] to [31fe76fcd7].
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 .. 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 .. 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 .. 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
if val then return os.execute(cmd) else
local fd = io.popen(cmd,'r')
local t = fd:read('*a')
return chomp(t), fd:close()
end
end
local function dump(v,pfx,cyc)
pfx = pfx or ''
cyc = cyc or {}
local np = pfx .. ' '
if type(v) == 'table' then
if cyc[v] then return '<...>' else cyc[v] = true end
end
................................................................................
return string.format('%q', v)
elseif type(v) == 'table' then
local str = ''
for k,v in pairs(v) do
local tkey, tval = dump(k,np,cyc), dump(v,np,cyc)
str = str .. string.format('%s[%s] = %s\n', np, tkey,tval)
end
return '{\n' .. str .. pfx .. '}\n'
else
return string.format('%s', v)
end
end
local ping = function(path)
local f = io.open(path)
if f then f:close() return true end
return false
end
local tobool = function(s)
if s == true then return true
................................................................................
local seed = 1 for i = 1, 8 do
seed = seed * string.byte(string.sub(ent,i,i))
end
math.randomseed(seed)
else math.randomseed(os.time()) end
return {
exec = exec;
dump = dump;
ping = ping;
chomp = chomp;
map = map;
tobool = tobool;
find = function(lst,pred)
for k,v in pairs(lst) do
local test = pred(v,k)
if test then return test end
end
return nil
end;
................................................................................
s = s .. string.char(ofs)
end
return s
end;
append = function(a,b)
for _, v in pairs(b) do a[#a+1] = v end
end;
has = function(haystack,needle,eq)
eq = eq or function(a,b) return a == b end
for k,v in pairs(haystack) do
if eq(needle,v) then return k end
end
end;
keys = function(ary)
local kt = {}
for k,v in pairs(ary) do kt[#kt+1] = k end
return kt
end;
|
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > | > > < | < < > | | | > > > | |
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 .. 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 ... 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 ... 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
if val then return os.execute(cmd) else
local fd = io.popen(cmd,'r')
local t = fd:read('*a')
return chomp(t), fd:close()
end
end
local function copy(a)
local new = {}
for k,v in pairs(a) do new[k] = v end
return new
end
local function cat(a,b)
a = copy(a)
local ofs = #a
for k,v in pairs(b) do
if type(k) == 'number' then
a[k+ofs] = v
else a[k] = v end
end
return a
end
local function search(tbl,pred,lst,path)
lst = lst or {} path = path or {}
if type(pred) ~= 'function' then
local val = pred
pred = function(a,k)
if type(a) == 'table' and a ~= val then return end
return a == val
end
end
for k,v in pairs(tbl) do
local res = pred(v,k)
local np = cat(path, {tbl})
if res == true then
table.insert(lst, {
key = k;
value = v;
parent = tbl;
path = np;
})
elseif res == nil then
search(v,pred,lst,np)
end
end
return lst
end
local function dump(v,pfx,cyc,ismeta)
pfx = pfx or ''
cyc = cyc or {}
local np = pfx .. ' '
if type(v) == 'table' then
if cyc[v] then return '<...>' else cyc[v] = true end
end
................................................................................
return string.format('%q', v)
elseif type(v) == 'table' then
local str = ''
for k,v in pairs(v) do
local tkey, tval = dump(k,np,cyc), dump(v,np,cyc)
str = str .. string.format('%s[%s] = %s\n', np, tkey,tval)
end
local meta = ''
if getmetatable(v) then
meta = dump(getmetatable(v),pfx,cyc,true) .. '::'
end
if ismeta then
return string.format('%s<|\n%s%s|>',meta,str,pfx)
else
return meta..'{\n' .. str .. pfx .. '}\n'
end
else
return string.format('%s', v)
end
end
local ping = function(path)
local f = io.open(path)
if f then f:close() return true end
return false
end
local tobool = function(s)
if s == true then return true
................................................................................
local seed = 1 for i = 1, 8 do
seed = seed * string.byte(string.sub(ent,i,i))
end
math.randomseed(seed)
else math.randomseed(os.time()) end
return {
dump = dump;
exec = exec, ping = ping;
map = map, copy = copy, cat = cat, search = search;
chomp = chomp, tobool = tobool;
find = function(lst,pred)
for k,v in pairs(lst) do
local test = pred(v,k)
if test then return test end
end
return nil
end;
................................................................................
s = s .. string.char(ofs)
end
return s
end;
append = function(a,b)
for _, v in pairs(b) do a[#a+1] = v end
end;
has = function(haystack,pred)
if type(pred) ~= 'function' then
local val = pred
pred = function(a) return a == val end
end
for k,v in pairs(haystack) do
if pred(v,k) then return k,v end
end
end;
keys = function(ary)
local kt = {}
for k,v in pairs(ary) do kt[#kt+1] = k end
return kt
end;
|
Modified mem.t from [8c252399a5] to [d10508934e].
106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
self.ct = self.ct - n
return self.ptr
end
terra t.methods.null(): t return t { ptr = nil, ct = 0 } end -- maybe should be a macro?
terra t:ref() return self.ptr ~= nil end
t.metamethods.__not = macro(function(self) return `not self:ref() end)
t.metamethods.__apply = macro(function(self,idx) return `self.ptr[ [idx or 0] ] end)
t.metamethods.__update = macro(function(self,idx,rhs)
return quote self.ptr[idx] = rhs end end)
t.metamethods.__cast = function(from,to,exp)
if to == t then
if from == niltype then return `t.null()
elseif from == &ty then return `t {ptr = exp, ct = 1}
elseif from == ty then return `t {ptr = &exp, ct = 1}
|
> > > |
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
self.ct = self.ct - n
return self.ptr
end
terra t.methods.null(): t return t { ptr = nil, ct = 0 } end -- maybe should be a macro?
terra t:ref() return self.ptr ~= nil end
t.metamethods.__not = macro(function(self) return `not self:ref() end)
t.metamethods.__apply = macro(function(self,idx) return `self.ptr[ [idx or 0] ] end)
t.metamethods.__add = terra(self: &t, sz: intptr): t
var n = @self n:advance(sz) return n
end
t.metamethods.__update = macro(function(self,idx,rhs)
return quote self.ptr[idx] = rhs end end)
t.metamethods.__cast = function(from,to,exp)
if to == t then
if from == niltype then return `t.null()
elseif from == &ty then return `t {ptr = exp, ct = 1}
elseif from == ty then return `t {ptr = &exp, ct = 1}
|
Modified route.t from [8f0d6bf9b0] to [325df84c8e].
923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 |
return end
::e404:: do co:complain(404, 'artifact not found', 'no such artifact has been uploaded to this instance') return end
end
local json = {}
terra json.webfinger(co: &lib.srv.convo)
end
-- entry points
terra r.dispatch_http(co: &lib.srv.convo, uri: lib.mem.ptr(int8), meth: method.t)
lib.dbg('handling URI of form ', {uri.ptr,uri.ct})
co.navbar = lib.render.nav(co)
-- some routes are non-hierarchical, and can be resolved with a simple strcmp
|
> > > > > > | > > | > > > > > > > > > > > > > > > > > > > > > |
923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 |
return end
::e404:: do co:complain(404, 'artifact not found', 'no such artifact has been uploaded to this instance') return end
end
local json = {}
do wftpl = lib.tpl.mk [[{
"subject": @$subj,
"links": [
{ "rel": "self", "type": "application/ld+json", "href": @$href }
]
}]]
terra json.webfinger(co: &lib.srv.convo)
var res = co:pgetv('resource')
if (not res) or not res:startswith 'acct:' then goto err end
-- technically we should look this user up in the database to make sure
-- they actually exist, buuut that's costly and i doubt that's actually
-- necessary for webfinger to do its job. so we cheat and just do string
-- munging so lookups are as cheap as possible. TODO make sure this works
-- in practice and doesn't cause any weird security problems
var acct = res + 5
var svp = lib.str.find(acct, '@')
if svp:ref() then
acct.ct = (svp.ptr - acct.ptr)
svp:advance(1)
if not svp:cmp(co.srv.cfg.domain) then goto err end
end
var tp = wftpl {
subj = res;
href = co:qstr('https://', co.srv.cfg.domain, '/@', acct);
}
co:json(tp:poolstr(&co.srv.pool))
do return end -- error conditions
::err:: do co:json('{}') return end
end
end
-- entry points
terra r.dispatch_http(co: &lib.srv.convo, uri: lib.mem.ptr(int8), meth: method.t)
lib.dbg('handling URI of form ', {uri.ptr,uri.ct})
co.navbar = lib.render.nav(co)
-- some routes are non-hierarchical, and can be resolved with a simple strcmp
|
Modified srv.t from [c8974a3f52] to [557555fd0b].
8 9 10 11 12 13 14 15 16 17 18 19 20 21 .. 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 ... 507 508 509 510 511 512 513 514 515 516 517 518 519 520 ... 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 .... 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 |
pol_sec: secmode.t pol_reg: bool pol_autoherald: bool credmgd: bool maxupsz: intptr poolinitsz: intptr instance: pstring overlord: &srv ui_cue_staff: pstring ui_cue_founder: pstring ui_hue: uint16 nranks: uint16 maxinvites: uint16 master: uint64 ................................................................................ webmgr: lib.net.mg_mgr webcon: &lib.net.mg_connection cfg: cfgcache id: rawstring pool: lib.mem.pool } terra cfgcache:free() -- :/ self.secret:free() self.instance:free() self.ui_cue_staff:free() self.ui_cue_founder:free() self.usrdef_pol_follow:free() self.usrdef_pol_follow_req:free() end terra srv:post_enum_author_uid(uid: uint64, r: lib.store.range): lib.mem.vec(lib.mem.ptr(lib.store.post)) ................................................................................ local route = {} -- these are defined in route.t, as they need access to renderers terra route.dispatch_http :: {&convo, lib.mem.ptr(int8), lib.http.method.t} -> {} local mimetypes = { {'html', 'text/html'}; {'json', 'application/json'}; {'mkdown', 'text/markdown'}; {'text', 'text/plain'}; {'ansi', 'text/x-ansi'}; } local mimevar = symbol(lib.mem.ref(int8)) local mimeneg = `lib.http.mime.none ................................................................................ in ret end end local handle = { http = terra(con: &lib.net.mg_connection, event_kind: int, event: &opaque, userdata: &opaque) var server = [&srv](userdata) var mgpeer = getpeer(con) var peer = lib.store.inet { port = mgpeer.port; } if mgpeer.is_ip6 then peer.pv = 6 else peer.pv = 4 end if peer.pv == 6 then for i = 0, 16 do peer.v6[i] = mgpeer.ip6[i] end else -- v4 @[&uint32](&peer.v4) = mgpeer.ip end -- the peer property is currently broken and there is precious -- little i can do about this -- it always reports a peer v4 IP -- of 0.0.0.0, altho the port seems to come through correctly. -- for now i'm leaving it as is, but note that netmask restrictions -- WILL NOT WORK until upstream gets its shit together. FIXME -- needs to check for an X-Forwarded-For header from nginx and -- use that instead of the peer iff peer is ::1/127.1 FIXME -- maybe also haproxy support? switch event_kind do case lib.net.MG_EV_HTTP_MSG then lib.dbg('routing HTTP request') var msg = [&lib.net.mg_http_message](event) var co = convo { con = con, srv = server, msg = msg; aid = 0, aid_issue = 0, who = nil; reqtype = lib.http.mime.none; peer = peer, live_last = 0; ................................................................................ str:free() end return default end terra cfgcache:load() self.instance = self.overlord:conf_get('instance-name') self.secret = self.overlord:conf_get('server-secret') self.pol_reg = self:cfbool('policy-self-register', false) self.pol_autoherald = self:cfbool('policy-self-herald', true) do self.credmgd = false var sreg = self.overlord:conf_get('credential-store') |
> | > > > | < < < < < < > | | > | > > > > > > > > > > > |
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 .. 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 ... 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 ... 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 .... 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 |
pol_sec: secmode.t pol_reg: bool pol_autoherald: bool credmgd: bool maxupsz: intptr poolinitsz: intptr instance: pstring domain: pstring overlord: &srv ui_cue_staff: pstring ui_cue_founder: pstring ui_hue: uint16 nranks: uint16 maxinvites: uint16 master: uint64 ................................................................................ webmgr: lib.net.mg_mgr webcon: &lib.net.mg_connection cfg: cfgcache id: rawstring pool: lib.mem.pool } terra cfgcache:free() -- :/ TODO replace with pool self.secret:free() self.instance:free() self.domain:free() self.ui_cue_staff:free() self.ui_cue_founder:free() self.usrdef_pol_follow:free() self.usrdef_pol_follow_req:free() end terra srv:post_enum_author_uid(uid: uint64, r: lib.store.range): lib.mem.vec(lib.mem.ptr(lib.store.post)) ................................................................................ local route = {} -- these are defined in route.t, as they need access to renderers terra route.dispatch_http :: {&convo, lib.mem.ptr(int8), lib.http.method.t} -> {} local mimetypes = { {'html', 'text/html'}; {'json', 'application/json'}; {'json', 'application/ld+json'}; {'json', 'application/activity+json'}; {'mkdown', 'text/markdown'}; {'text', 'text/plain'}; {'ansi', 'text/x-ansi'}; } local mimevar = symbol(lib.mem.ref(int8)) local mimeneg = `lib.http.mime.none ................................................................................ in ret end end local handle = { http = terra(con: &lib.net.mg_connection, event_kind: int, event: &opaque, userdata: &opaque) var server = [&srv](userdata) var mgpeer = getpeer(con) -- var pbuf: int8[128] -- the peer property is currently broken and there is precious -- little i can do about this -- it always reports a peer v4 IP -- of 0.0.0.0 for v6 connections, altho the port seems to come -- through correctly. -- for now i'm leaving it as is, but note -- that netmask restrictions WILL NOT WORK until upstream gets -- its shit together. FIXME -- needs to check for an X-Forwarded-For header from nginx and -- use that instead of the peer iff peer is ::1/127.1 FIXME -- maybe also haproxy support? switch event_kind do case lib.net.MG_EV_HTTP_MSG then -- lib.net.mg_ntoa(&mgpeer,&pbuf[0],127) -- lib.dbg('got connection from client ',&pbuf[0]) var peer = lib.store.inet { port = mgpeer.port; } if mgpeer.is_ip6 then peer.pv = 6 else peer.pv = 4 end if peer.pv == 6 then for i = 0, 16 do peer.v6[i] = mgpeer.ip6[i] end else -- v4 @[&uint32](&peer.v4) = mgpeer.ip end lib.dbg('routing HTTP request') var msg = [&lib.net.mg_http_message](event) var co = convo { con = con, srv = server, msg = msg; aid = 0, aid_issue = 0, who = nil; reqtype = lib.http.mime.none; peer = peer, live_last = 0; ................................................................................ str:free() end return default end terra cfgcache:load() self.instance = self.overlord:conf_get('instance-name') self.domain = self.overlord:conf_get('domain') self.secret = self.overlord:conf_get('server-secret') self.pol_reg = self:cfbool('policy-self-register', false) self.pol_autoherald = self:cfbool('policy-self-herald', true) do self.credmgd = false var sreg = self.overlord:conf_get('credential-store') |
Modified str.t from [0c9ba1d780] to [6c699847d5].
59
60
61
62
63
64
65
66
67
68
69
70
71
72
...
559
560
561
562
563
564
565
566
567
|
var sz = lib.math.biggest(self.ct, other.ct)
for i = 0, sz do
if self.ptr[i] == 0 and other.ptr[i] == 0 then return true end
if self.ptr[i] ~= other.ptr[i] then return false end
end
return true
end
terra ty:ffw()
var newp = m.ffw(self.ptr,self.ct)
var newct = self.ct - (newp - self.ptr)
return ty { ptr = newp, ct = newct }
end
terra ty:blob()
................................................................................
var cur = str while cur.ct > 0 do
var add, cont = disemvowel_codepoint(cur)
if add:ref() then acc:ppush(add) end
cur = cont
end
return acc:finalize()
end
return m
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
...
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
|
var sz = lib.math.biggest(self.ct, other.ct) for i = 0, sz do if self.ptr[i] == 0 and other.ptr[i] == 0 then return true end if self.ptr[i] ~= other.ptr[i] then return false end end return true end terra ty:startswith(other: ty) for i=0, other.ct do if other(i) == 0 then return true end if other(i) ~= self(i) then return false end end return true end terra ty:ffw() var newp = m.ffw(self.ptr,self.ct) var newct = self.ct - (newp - self.ptr) return ty { ptr = newp, ct = newct } end terra ty:blob() ................................................................................ var cur = str while cur.ct > 0 do var add, cont = disemvowel_codepoint(cur) if add:ref() then acc:ppush(add) end cur = cont end return acc:finalize() end terra m.qesc(pool: &lib.mem.pool, str: m.t): m.t -- escape double-quotes var a: m.acc a:pool(pool, str.ct + str.ct/2) a:lpush '"' for i=0, str.ct do if str(i) == @'"' then a:lpush '\\"' elseif str(i) == @'\\' then a:lpush '\\\\' elseif str(i) < 0x20 then -- for json var hex = lib.math.hexbyte(str(i)) a:lpush('\\u00'):push(&hex[0], 2) else a:push(str.ptr + i,1) end end a:lpush '"' return a:finalize() end return m |
Modified tpl.t from [7216746946] to [ce74a1083d].
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 .. 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 .. 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
str = str:gsub('%s+[\n$]','')
str = str:gsub('\n','')
str = str:gsub('</a><a ','</a> <a ') -- keep nav links from getting smooshed
str = str:gsub(tplchar .. '%?([-%w]+)', function(file)
if not docs[file] then docs[file] = data.doc[file] end
return string.format('<a href="#help-%s" class="help">?</a>', file)
end)
for start, mode, key, stop in string.gmatch(str,'()'..tplchar..'([:!]?)([-a-zA-Z0-9_]+)()') do
if string.sub(str,start-1,start-1) ~= '\\' then
segs[#segs+1] = string.sub(str,last,start-1)
fields[#segs] = { key = key:gsub('-','_'), mode = (mode ~= '' and mode or nil) }
last = stop
end
end
segs[#segs+1] = string.sub(str,last)
................................................................................
if not kfac[fld.key] then
rec.entries[#rec.entries + 1] = {
field = fld.key;
type = lib.mem.ptr(int8);
}
end
kfac[fld.key] = (kfac[fld.key] or 0) + 1
sanmode[fld.key] = fld.mode == ':' and 6 or fld.mode == '!' and 5 or 1
end
for key, fac in pairs(kfac) do
local sanfac = sanmode[key]
tallyup[#tallyup + 1] = quote
[runningtally] = [runningtally] + ([symself].[key].ct)*fac*sanfac
end
................................................................................
for idx, seg in ipairs(segs) do
copiers[#copiers+1] = quote [cpypos] = lib.mem.cpy([cpypos], [&opaque]([seg]), [#seg]) end
senders[#senders+1] = quote lib.net.mg_send([destcon], [seg], [#seg]) end
appenders[#appenders+1] = quote [accumulator]:push([seg], [#seg]) end
if fields[idx] and fields[idx].mode then
local f = fields[idx]
local fp = `symself.[f.key]
copiers[#copiers+1] = quote
if fp.ct > 0 then
var san = lib.html.sanitize(pool, fp, [f.mode == ':'])
[cpypos] = lib.mem.cpy([cpypos], [&opaque](san.ptr), san.ct)
--san:free()
end
end
senders[#senders+1] = quote
if fp.ct > 0 then
var san = lib.html.sanitize(pool, fp, [f.mode == ':'])
lib.net.mg_send([destcon], san.ptr, san.ct)
--san:free()
end
end
appenders[#appenders+1] = quote
if fp.ct > 0 then
var san = lib.html.sanitize(pool, fp, [f.mode == ':'])
[accumulator]:ppush(san)
--san:free()
end
end
elseif fields[idx] then
local f = fields[idx]
local fp = `symself.[f.key]
|
| | > > > > > > > > < > | | |
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 .. 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 ... 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
str = str:gsub('%s+[\n$]','')
str = str:gsub('\n','')
str = str:gsub('</a><a ','</a> <a ') -- keep nav links from getting smooshed
str = str:gsub(tplchar .. '%?([-%w]+)', function(file)
if not docs[file] then docs[file] = data.doc[file] end
return string.format('<a href="#help-%s" class="help">?</a>', file)
end)
for start, mode, key, stop in string.gmatch(str,'()'..tplchar..'([:!$]?)([-a-zA-Z0-9_]+)()') do
if string.sub(str,start-1,start-1) ~= '\\' then
segs[#segs+1] = string.sub(str,last,start-1)
fields[#segs] = { key = key:gsub('-','_'), mode = (mode ~= '' and mode or nil) }
last = stop
end
end
segs[#segs+1] = string.sub(str,last)
................................................................................
if not kfac[fld.key] then
rec.entries[#rec.entries + 1] = {
field = fld.key;
type = lib.mem.ptr(int8);
}
end
kfac[fld.key] = (kfac[fld.key] or 0) + 1
sanmode[fld.key] = fld.mode == ':' and 6
or fld.mode == '!' and 5
or fld.mode == '$' and 2 or 1
end
for key, fac in pairs(kfac) do
local sanfac = sanmode[key]
tallyup[#tallyup + 1] = quote
[runningtally] = [runningtally] + ([symself].[key].ct)*fac*sanfac
end
................................................................................
for idx, seg in ipairs(segs) do
copiers[#copiers+1] = quote [cpypos] = lib.mem.cpy([cpypos], [&opaque]([seg]), [#seg]) end
senders[#senders+1] = quote lib.net.mg_send([destcon], [seg], [#seg]) end
appenders[#appenders+1] = quote [accumulator]:push([seg], [#seg]) end
if fields[idx] and fields[idx].mode then
local f = fields[idx]
local fp = `symself.[f.key]
local sanexp
if f.mode == '$' then
sanexp = `lib.str.qesc(pool, fp)
else
sanexp = `lib.html.sanitize(pool, fp, [f.mode == ':'])
end
copiers[#copiers+1] = quote
if fp.ct > 0 then
var san = sanexp
[cpypos] = lib.mem.cpy([cpypos], [&opaque](san.ptr), san.ct)
--san:free()
end
end
senders[#senders+1] = quote
if fp.ct > 0 then
var san = sanexp
lib.net.mg_send([destcon], san.ptr, san.ct)
--san:free()
end
end
appenders[#appenders+1] = quote
if fp.ct > 0 then
var san = sanexp
[accumulator]:ppush(san)
--san:free()
end
end
elseif fields[idx] then
local f = fields[idx]
local fp = `symself.[f.key]
|