5
6
7
8
9
10
11
12
13
14
15
16
17
18
..
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
...
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
...
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
...
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
...
853
854
855
856
857
858
859
860
861
862
863
864
865
866
...
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
...
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
...
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
|
local struct srv
local struct cfgcache {
secret: pstring
pol_sec: secmode.t
pol_reg: bool
credmgd: bool
maxupsz: intptr
instance: pstring
overlord: &srv
ui_cue_staff: pstring
ui_cue_founder: pstring
ui_hue: uint16
nranks: uint16
maxinvites: uint16
................................................................................
}
local struct srv {
sources: lib.mem.ptr(lib.store.source)
webmgr: lib.net.mg_mgr
webcon: &lib.net.mg_connection
cfg: cfgcache
id: rawstring
}
terra cfgcache:free() -- :/
self.secret:free()
self.instance:free()
self.ui_cue_staff:free()
self.ui_cue_founder:free()
................................................................................
terra convo:confirm(title: pstring, msg: pstring, cancel: pstring)
var conf = data.view.confirm {
title = title;
query = msg;
cancel = cancel;
}
var ti: lib.str.acc ti:compose('confirm :: ', title)
var body = conf:tostr() defer body:free()
var cf = [convo.page] {
title = ti:finalize();
class = lib.str.plit 'query';
body = body; cache = false;
}
self:stdpage(cf)
cf.title:free()
end
convo.methods.assertpow = macro(function(self, pow)
return quote
var ok = true
if self.aid == 0 or self.who.rights.powers.[pow:asvalue()]() == false then
ok = false
................................................................................
end
in ok end
end)
-- CALL ONLY ONCE PER VAR
terra convo:postv(name: rawstring)
if self.varbuf.ptr == nil then
self.varbuf = lib.mem.heapa(int8, self.msg.body.len + self.msg.query.len)
self.vbofs = self.varbuf.ptr
end
var o = lib.net.mg_http_get_var(&self.msg.body, name, self.vbofs, self.varbuf.ct - (self.vbofs - self.varbuf.ptr))
if o > 0 then
var r = self.vbofs
self.vbofs = self.vbofs + o + 1
@(self.vbofs - 1) = 0
................................................................................
terra convo:ppostv(name: rawstring)
var s,l = self:postv(name)
return pstring { ptr = s, ct = l }
end
terra convo:getv(name: rawstring)
if self.varbuf.ptr == nil then
self.varbuf = lib.mem.heapa(int8, self.msg.query.len + self.msg.body.len)
self.vbofs = self.varbuf.ptr
end
var o = lib.net.mg_http_get_var(&self.msg.query, name, self.vbofs, self.varbuf.ct - (self.vbofs - self.varbuf.ptr))
if o > 0 then
var r = self.vbofs
self.vbofs = self.vbofs + o + 1
@(self.vbofs - 1) = 0
................................................................................
var livelast_p = lib.http.findheader(msg, 'X-Live-Last-Arrival')
if livelast_p ~= nil and livelast_p.ptr ~= nil then
var ll, ok = lib.math.decparse(pstring{ptr = livelast_p.ptr, ct = livelast_p.ct - 1})
if ok then co.live_last = ll end
end
var uridec = lib.mem.heapa(int8, msg.uri.len) defer uridec:free()
var urideclen = lib.net.mg_url_decode(msg.uri.ptr, msg.uri.len, uridec.ptr, uridec.ct, 1)
var uri = uridec
if urideclen == -1 then
for i = 0,msg.uri.len do
if msg.uri.ptr[i] == @'+'
then uri.ptr[i] = @' '
................................................................................
bsr:free()
upmap:free()
end
end
end
route.dispatch_http(&co, uri, co.method)
if co.uploads.run > 0 then
for i=0,co.uploads.sz do
co.uploads(i).filename:free()
co.uploads(i).field:free()
end
co.uploads:free()
end
::fail::
if co.aid ~= 0 then lib.mem.heapf(co.who) end
if co.varbuf.ptr ~= nil then co.varbuf:free() end
if co.navbar.ptr ~= nil then co.navbar:free() end
co.actorcache:free()
end
end
end;
}
local terra cfg(s: &srv, befile: rawstring)
lib.report('configuring backends from ', befile)
................................................................................
lib.bail('could not connect to any data sources!')
end
end
terra srv:start(iname: rawstring)
self:conprep(lib.store.prepmode.full)
self.cfg:init(self)
var dbbind = self:conf_get('bind')
if iname == nil then iname = lib.proc.getenv('parsav_instance') end
if iname == nil then
self.id = self.cfg.instance.ptr;
-- let this leak -- it'll be needed for the lifetime of the process anyway
else self.id = iname end
................................................................................
terra srv:shutdown()
lib.net.mg_mgr_free(&self.webmgr)
for i=0,self.sources.ct do var src = self.sources.ptr + i
lib.report('closing data source ', src.id.ptr, '(', src.backend.id, ')')
src:close()
end
self.sources:free()
end
terra cfgcache:cfint(name: rawstring, default: intptr)
var str = self.overlord:conf_get(name)
if str.ptr ~= nil then
var i,ok = lib.math.decparse(str)
if ok then default = i else
lib.warn('invalid configuration setting ',name,'="',{str.ptr,str.ct},'", expected integer; using default value instead')
end
str:free()
end
return default
end
terra cfgcache:cfbool(name: rawstring, default: bool)
var str = self.overlord:conf_get(name)
if str.ptr ~= nil then
................................................................................
if lib.str.cmp(sreg.ptr, 'managed') == 0
then self.credmgd = true
else self.credmgd = false
end
sreg:free()
end end
do self.maxupsz = [1024 * 100] -- 100 kilobyte default
var sreg = self.overlord:conf_get('maximum-artifact-size')
if sreg:ref() then
var sz, ok = lib.math.fsz_parse(sreg)
if ok then self.maxupsz = sz else
lib.warn('invalid configuration value for maximum-artifact-size; keeping default 100K upload limit')
end
sreg:free() end
end
self.pol_sec = secmode.lockdown
var smode = self.overlord:conf_get('policy-security')
if smode.ptr ~= nil then
if lib.str.cmp(smode.ptr, 'public') == 0 then
self.pol_sec = secmode.public
elseif lib.str.cmp(smode.ptr, 'private') == 0 then
................................................................................
self.nranks = self:cfint('user-ranks',10)
self.maxinvites = self:cfint('max-invites',64)
var webmaster = self.overlord:conf_get('master')
if webmaster:ref() then defer webmaster:free()
var wma = self.overlord:actor_fetch_xid(webmaster)
if not wma then
lib.warn('the webmaster specified in the configuration store does not seem to exist or is not known to this instance; preceding as if no master defined. if the master is a remote user, you can rectify this with the `actor ',{webmaster.ptr,webmaster.ct},' instantiate` and `conf refresh` commands')
else
self.master = wma(0).id
wma:free()
end
end
self.ui_cue_staff = self.overlord:conf_get('ui-profile-cue-staff')
|
>
>
|
|
|
>
>
>
>
>
>
|
|
|
>
>
<
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
<
<
<
<
<
<
|
|
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
...
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
...
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
...
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
...
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
...
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
...
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
...
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
|
local struct srv
local struct cfgcache {
secret: pstring
pol_sec: secmode.t
pol_reg: 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
................................................................................
}
local struct srv {
sources: lib.mem.ptr(lib.store.source)
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()
................................................................................
terra convo:confirm(title: pstring, msg: pstring, cancel: pstring)
var conf = data.view.confirm {
title = title;
query = msg;
cancel = cancel;
}
var ti: lib.str.acc ti:pcompose(&self.srv.pool,'confirm :: ', title)
var body = conf:poolstr(&self.srv.pool) -- defer body:free()
var cf = [convo.page] {
title = ti:finalize();
class = lib.str.plit 'query';
body = body; cache = false;
}
self:stdpage(cf)
--cf.title:free()
end
terra convo:stra(sz: intptr) -- convenience function
var s: lib.str.acc
s:pool(&self.srv.pool,sz)
return s
end
convo.methods.assertpow = macro(function(self, pow)
return quote
var ok = true
if self.aid == 0 or self.who.rights.powers.[pow:asvalue()]() == false then
ok = false
................................................................................
end
in ok end
end)
-- CALL ONLY ONCE PER VAR
terra convo:postv(name: rawstring)
if self.varbuf.ptr == nil then
self.varbuf = self.srv.pool:alloc(int8, self.msg.body.len + self.msg.query.len)
self.vbofs = self.varbuf.ptr
end
var o = lib.net.mg_http_get_var(&self.msg.body, name, self.vbofs, self.varbuf.ct - (self.vbofs - self.varbuf.ptr))
if o > 0 then
var r = self.vbofs
self.vbofs = self.vbofs + o + 1
@(self.vbofs - 1) = 0
................................................................................
terra convo:ppostv(name: rawstring)
var s,l = self:postv(name)
return pstring { ptr = s, ct = l }
end
terra convo:getv(name: rawstring)
if self.varbuf.ptr == nil then
self.varbuf = self.srv.pool:alloc(int8, self.msg.query.len + self.msg.body.len)
self.vbofs = self.varbuf.ptr
end
var o = lib.net.mg_http_get_var(&self.msg.query, name, self.vbofs, self.varbuf.ct - (self.vbofs - self.varbuf.ptr))
if o > 0 then
var r = self.vbofs
self.vbofs = self.vbofs + o + 1
@(self.vbofs - 1) = 0
................................................................................
var livelast_p = lib.http.findheader(msg, 'X-Live-Last-Arrival')
if livelast_p ~= nil and livelast_p.ptr ~= nil then
var ll, ok = lib.math.decparse(pstring{ptr = livelast_p.ptr, ct = livelast_p.ct - 1})
if ok then co.live_last = ll end
end
var uridec = server.pool:alloc(int8, msg.uri.len)
var urideclen = lib.net.mg_url_decode(msg.uri.ptr, msg.uri.len, uridec.ptr, uridec.ct, 1)
var uri = uridec
if urideclen == -1 then
for i = 0,msg.uri.len do
if msg.uri.ptr[i] == @'+'
then uri.ptr[i] = @' '
................................................................................
bsr:free()
upmap:free()
end
end
end
route.dispatch_http(&co, uri, co.method)
::fail::
if co.uploads.run > 0 then
for i=0,co.uploads.sz do
co.uploads(i).filename:free()
co.uploads(i).field:free()
end
co.uploads:free()
end
if co.aid ~= 0 then lib.mem.heapf(co.who) end
-- if co.varbuf.ptr ~= nil then co.varbuf:free() end
-- if co.navbar.ptr ~= nil then co.navbar:free() end
co.actorcache:free()
server.pool:clear()
end
end
end;
}
local terra cfg(s: &srv, befile: rawstring)
lib.report('configuring backends from ', befile)
................................................................................
lib.bail('could not connect to any data sources!')
end
end
terra srv:start(iname: rawstring)
self:conprep(lib.store.prepmode.full)
self.cfg:init(self)
self.pool:init(self.cfg.poolinitsz)
var dbbind = self:conf_get('bind')
if iname == nil then iname = lib.proc.getenv('parsav_instance') end
if iname == nil then
self.id = self.cfg.instance.ptr;
-- let this leak -- it'll be needed for the lifetime of the process anyway
else self.id = iname end
................................................................................
terra srv:shutdown()
lib.net.mg_mgr_free(&self.webmgr)
for i=0,self.sources.ct do var src = self.sources.ptr + i
lib.report('closing data source ', src.id.ptr, '(', src.backend.id, ')')
src:close()
end
self.sources:free()
self.pool:free()
end
terra cfgcache:cfint(name: rawstring, default: intptr)
var str = self.overlord:conf_get(name)
if str.ptr ~= nil then
var i,ok = lib.math.decparse(str)
if ok then default = i else
lib.warn('invalid configuration setting ',name,'="',{str.ptr,str.ct},'", expected integer; using default value instead')
end
str:free()
end
return default
end
terra cfgcache:cffsz(name: rawstring, default: intptr)
var str = self.overlord:conf_get(name)
if str:ref() then
var sz, ok = lib.math.fsz_parse(str)
if ok then default = sz else
lib.warn('invalid configuration setting ',name,'="',{str.ptr,str.ct},'", expected byte length; using default value instead')
end
str:free()
end
return default
end
terra cfgcache:cfbool(name: rawstring, default: bool)
var str = self.overlord:conf_get(name)
if str.ptr ~= nil then
................................................................................
if lib.str.cmp(sreg.ptr, 'managed') == 0
then self.credmgd = true
else self.credmgd = false
end
sreg:free()
end end
self.maxupsz = self:cffsz('maximum-artifact-size', [1024 * 100]) -- 100 kilobyte default
self.poolinitsz = self:cffsz('server-pool-size-initial', [1024 * 10]) -- 10 kilobyte default
self.pol_sec = secmode.lockdown
var smode = self.overlord:conf_get('policy-security')
if smode.ptr ~= nil then
if lib.str.cmp(smode.ptr, 'public') == 0 then
self.pol_sec = secmode.public
elseif lib.str.cmp(smode.ptr, 'private') == 0 then
................................................................................
self.nranks = self:cfint('user-ranks',10)
self.maxinvites = self:cfint('max-invites',64)
var webmaster = self.overlord:conf_get('master')
if webmaster:ref() then defer webmaster:free()
var wma = self.overlord:actor_fetch_xid(webmaster)
if not wma then
lib.warn('the webmaster specified in the configuration store does not seem to exist or is not known to this instance; preceding as if no master defined. if the master is a remote user, you can rectify this with the `actor "',{webmaster.ptr,webmaster.ct},'" instantiate` and `conf refresh` commands')
else
self.master = wma(0).id
wma:free()
end
end
self.ui_cue_staff = self.overlord:conf_get('ui-profile-cue-staff')
|