parsav  Diff

Differences From Artifact [80adbc5ad3]:

To Artifact [854410a8ca]:


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')