237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
...
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
...
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
...
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
|
terra convo:stdpage(pg: convo.page) self:statpage(200, pg) end
terra convo:bytestream(mime: pstring, data: lib.mem.ptr(uint8))
-- TODO this is not a satisfactory solution; it's a bandaid on a gaping
-- chest wound. ultimately we need to compile a whitelist of safe mime
-- types as part of mimelib, but that is no small task. for now, this
-- will keep the patient from immediately bleeding out
if mime:cmp(lib.str.plit'text/html') or
mime:cmp(lib.str.plit'text/xml') or
mime:cmp(lib.str.plit'application/xhtml+xml') or
mime:cmp(lib.str.plit'application/vnd.wap.xhtml+xml')
then -- danger will robinson
mime = lib.str.plit'text/plain'
elseif mime:cmp(lib.str.plit'application/x-shockwave-flash') then
mime = lib.str.plit'application/octet-stream'
end
lib.net.mg_printf(self.con, "HTTP/1.1 200 OK\r\nContent-Type: %.*s\r\nContent-Length: %llu\r\nContent-Security-Policy: sandbox; default-src 'none'; form-action 'none'; navigate-to 'none';\r\nX-Content-Options: nosniff\r\n\r\n", mime.ct, mime.ptr, data.ct + 2)
lib.net.mg_send(self.con, data.ptr, data.ct)
lib.net.mg_send(self.con, '\r\n', 2)
end
terra convo:reroute_cookie(dest: rawstring, cookie: rawstring)
................................................................................
if msg == nil then msg = "i'm sorry, dave. i can't let you do that" end
var ti: lib.str.acc ti:compose('error :: ', title)
var bo: lib.str.acc bo:compose('<div class="message"><img class="icon" src="/s/warn.svg"><h1>',title,'</h1><p>',msg,'</p></div>')
var body = [convo.page] {
title = ti:finalize();
body = bo:finalize();
class = lib.str.plit 'error';
cache = false;
}
self:statpage(code, body)
body.title:free()
body.body:free()
................................................................................
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 halt = lib.str.find(@lsent, lsr)
if halt:ref() then
lsent.ct = halt.ptr - lsent.ptr
end
lsr:free() end
for i=0,upmap.ct do
var hdrbrk = lib.str.find(upmap(i), lib.str.plit'\r\n\r\n')
if hdrbrk:ref() then
var hdrtxt = pstring {upmap(i).ptr,upmap(i).ct - hdrbrk.ct}
var hdrs = lib.str.splitmap(hdrtxt, '\r\n',6)
var ctt = pstring.null()
var ctd = pstring.null()
for j=0, hdrs.ct do
var brk = lib.str.find(hdrs(j),lib.str.plit':')
if brk:ref() then
var hdr = pstring{hdrs(j).ptr,hdrs(j).ct - brk.ct}
var val = pstring{brk.ptr+1, brk.ct-1}:ffw()
if hdr:cmp(lib.str.plit'Content-Type') then
ctt = val
elseif hdr:cmp(lib.str.plit'Content-Disposition') then
ctd = val
end
end
end
if ctd:ref() then
var ctdvals = lib.str.splitmap(ctd, ';', 4) defer ctdvals:free()
if ctdvals(0):cmp(lib.str.plit'form-data') and ctdvals.ct > 1 then
var fld = pstring.null()
var file = pstring.null()
for j=1, ctdvals.ct do var v = ctdvals(j):ffw()
var x = lib.str.find(v,lib.str.plit'=')
if x:ref() then
var key = pstring{v.ptr, v.ct - x.ct}
var val = pstring{x.ptr + 1, x.ct - 1}
var decval, ofs, sp = lib.str.toknext(val,@';',true)
if key:cmp(lib.str.plit'name') then
fld = decval
elseif key:cmp(lib.str.plit'filename') then
file = decval
else decval:free() end
end
end
if fld:ref() then
var nextup = co.uploads:new()
if ctt:ref() then
................................................................................
end
return default
end
terra cfgcache:cfbool(name: rawstring, default: bool)
var str = self.overlord:conf_get(name)
if str.ptr ~= nil then
if str:cmp(lib.str.plit 'true') or str:cmp(lib.str.plit 'on') or
str:cmp(lib.str.plit 'yes') or str:cmp(lib.str.plit '1') then
default = true
elseif str:cmp(lib.str.plit 'false') or str:cmp(lib.str.plit 'off') or
str:cmp(lib.str.plit 'no') or str:cmp(lib.str.plit '0') then
default = false
else
lib.warn('invalid configuration setting ',name,'="',{str.ptr,str.ct},'", expected boolean; using default value instead')
end
str:free()
end
return default
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
...
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
...
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
...
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
|
terra convo:stdpage(pg: convo.page) self:statpage(200, pg) end
terra convo:bytestream(mime: pstring, data: lib.mem.ptr(uint8))
-- TODO this is not a satisfactory solution; it's a bandaid on a gaping
-- chest wound. ultimately we need to compile a whitelist of safe mime
-- types as part of mimelib, but that is no small task. for now, this
-- will keep the patient from immediately bleeding out
if mime:cmp('text/html') or
mime:cmp('text/xml') or
mime:cmp('application/xhtml+xml') or
mime:cmp('application/vnd.wap.xhtml+xml')
then -- danger will robinson
mime = 'text/plain'
elseif mime:cmp('application/x-shockwave-flash') then
mime = 'application/octet-stream'
end
lib.net.mg_printf(self.con, "HTTP/1.1 200 OK\r\nContent-Type: %.*s\r\nContent-Length: %llu\r\nContent-Security-Policy: sandbox; default-src 'none'; form-action 'none'; navigate-to 'none';\r\nX-Content-Options: nosniff\r\n\r\n", mime.ct, mime.ptr, data.ct + 2)
lib.net.mg_send(self.con, data.ptr, data.ct)
lib.net.mg_send(self.con, '\r\n', 2)
end
terra convo:reroute_cookie(dest: rawstring, cookie: rawstring)
................................................................................
if msg == nil then msg = "i'm sorry, dave. i can't let you do that" end
var ti: lib.str.acc ti:compose('error :: ', title)
var bo: lib.str.acc bo:compose('<div class="message"><img class="icon" src="/s/warn.svg"><h1>',title,'</h1><p>',msg,'</p></div>')
var body = [convo.page] {
title = ti:finalize();
body = bo:finalize();
class = 'error';
cache = false;
}
self:statpage(code, body)
body.title:free()
body.body:free()
................................................................................
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 = 'query';
body = body; cache = false;
}
self:stdpage(cf)
--cf.title:free()
end
terra convo:stra(sz: intptr) -- convenience function
................................................................................
var halt = lib.str.find(@lsent, lsr)
if halt:ref() then
lsent.ct = halt.ptr - lsent.ptr
end
lsr:free() end
for i=0,upmap.ct do
var hdrbrk = lib.str.find(upmap(i), '\r\n\r\n')
if hdrbrk:ref() then
var hdrtxt = pstring {upmap(i).ptr,upmap(i).ct - hdrbrk.ct}
var hdrs = lib.str.splitmap(hdrtxt, '\r\n',6)
var ctt = pstring.null()
var ctd = pstring.null()
for j=0, hdrs.ct do
var brk = lib.str.find(hdrs(j),':')
if brk:ref() then
var hdr = pstring{hdrs(j).ptr,hdrs(j).ct - brk.ct}
var val = pstring{brk.ptr+1, brk.ct-1}:ffw()
if hdr:cmp('Content-Type') then
ctt = val
elseif hdr:cmp('Content-Disposition') then
ctd = val
end
end
end
if ctd:ref() then
var ctdvals = lib.str.splitmap(ctd, ';', 4) defer ctdvals:free()
if ctdvals(0):cmp('form-data') and ctdvals.ct > 1 then
var fld = pstring.null()
var file = pstring.null()
for j=1, ctdvals.ct do var v = ctdvals(j):ffw()
var x = lib.str.find(v,'=')
if x:ref() then
var key = pstring{v.ptr, v.ct - x.ct}
var val = pstring{x.ptr + 1, x.ct - 1}
var decval, ofs, sp = lib.str.toknext(val,@';',true)
if key:cmp('name') then
fld = decval
elseif key:cmp('filename') then
file = decval
else decval:free() end
end
end
if fld:ref() then
var nextup = co.uploads:new()
if ctt:ref() then
................................................................................
end
return default
end
terra cfgcache:cfbool(name: rawstring, default: bool)
var str = self.overlord:conf_get(name)
if str.ptr ~= nil then
if str:cmp('true') or str:cmp('on') or
str:cmp('yes') or str:cmp('1') then
default = true
elseif str:cmp('false') or str:cmp('off') or
str:cmp('no') or str:cmp('0') then
default = false
else
lib.warn('invalid configuration setting ',name,'="',{str.ptr,str.ct},'", expected boolean; using default value instead')
end
str:free()
end
return default
|