Overview
| Comment: | somewhat defuckulate build system |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
251b382f5c302eb3ca626d539ec46e98 |
| User & Date: | lexi on 2021-01-22 16:48:53 |
| Other Links: | manifest | tags |
Context
|
2021-01-22
| ||
| 17:18 | defuckulate bytestream_trusted check-in: 7af9e0961e user: lexi tags: trunk | |
| 16:48 | somewhat defuckulate build system check-in: 251b382f5c user: lexi tags: trunk | |
|
2021-01-19
| ||
| 22:02 | add dist mechanism check-in: d248dc5965 user: lexi tags: trunk | |
Changes
Modified config.lua from [cba33505b3] to [74b801cbf1].
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
if type(e) == 'function'
then return e(conf)
else return e
end
end
return coalesce(
pkgenv(v),
pkv(e or v),
(fbo and eval(fbo[v])),
(fbv and eval(fbv[v])))
end
local name = cnfvar('override') or name
local pcname = coalesce(cnfvar('pcname'), name)
if conf.posix then
pkc = function(...) if locdep then return nil end
................................................................................
end
else pkc = nul end
else
print '(warn) configuring on non-POSIX OS, all relevant paths must be specified manually in environment variables or build will fail!'
end
locdep = u.ping('./lib/' .. name)
local incdir, libdir, prefix
if locdep then
prefix = './lib/' .. name
libdir = prefix .. coalesce(cnfvar('libbuilddir'),cnfvar('builddir'),'')
incdir = prefix .. coalesce(cnfvar('srcincdir'),cnfvar('builddir'),'/include')
else
prefix = coalesce(cnfvar('prefix'), '/usr')
libdir = cnfvar('libdir')
incdir = cnfvar('incdir','includedir')
end
libdir = libdir or prefix .. '/lib'
incdir = incdir or prefix .. '/include'
local libstr = pkc '--libs-only-l' -- (--static is not reliable)
local libs = fb and fb.libs or {}
local linkstatic = locdep
if (not locdep) and libstr then
libs = {}
for m in string.gmatch(libstr, '-l(%g+)') do
|
|
>
>
|
|
|
|
>
|
>
|
|
|
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
|
if type(e) == 'function' then return e(conf) else return e end end return coalesce( pkgenv(v), e ~= false and pkv(e or v) or nil, (fbo and eval(fbo[v])), (fbv and eval(fbv[v]))) end local name = cnfvar('override') or name local pcname = coalesce(cnfvar('pcname'), name) if conf.posix then pkc = function(...) if locdep then return nil end ................................................................................ end else pkc = nul end else print '(warn) configuring on non-POSIX OS, all relevant paths must be specified manually in environment variables or build will fail!' end locdep = u.ping('./lib/' .. name) local incdir, libdir, prefix local libsfx = coalesce(cnfvar('libsuffix',false),'') local incsfx = coalesce(cnfvar('incsuffix',false),'') if locdep then prefix = './lib/' .. name libdir = prefix .. coalesce(cnfvar 'libbuilddir',cnfvar 'builddir','') incdir = prefix .. coalesce(cnfvar 'srcincdir', cnfvar 'builddir','/include') else prefix = coalesce(cnfvar 'prefix', '/usr') libdir = cnfvar 'libdir' if libdir then libdir = libdir .. libsfx end incdir = cnfvar('incdir','includedir') if incdir then incdir = incdir .. incsfx end end libdir = libdir or (prefix .. '/lib' .. libsfx) incdir = incdir or (prefix .. '/include' .. incsfx) local libstr = pkc '--libs-only-l' -- (--static is not reliable) local libs = fb and fb.libs or {} local linkstatic = locdep if (not locdep) and libstr then libs = {} for m in string.gmatch(libstr, '-l(%g+)') do |
Modified parsav.t from [b6e7e54998] to [dd405c9e82].
433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
lib.err = lib.loadlib('mbedtls','mbedtls/error.h')
lib.rsa = lib.loadlib('mbedtls','mbedtls/rsa.h')
lib.pk = lib.loadlib('mbedtls','mbedtls/pk.h')
lib.md = lib.loadlib('mbedtls','mbedtls/md.h')
lib.b64 = lib.loadlib('mbedtls','mbedtls/base64.h')
lib.net = lib.loadlib('mongoose','mongoose.h')
lib.pq = lib.loadlib('libpq','libpq-fe.h')
lib.load {
'mem', 'math', 'str', 'file', 'crypt', 'ipc';
'http', 'html', 'session', 'tpl', 'store', 'acl';
'smackdown'; -- md-alike parser
}
|
> |
433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 |
lib.err = lib.loadlib('mbedtls','mbedtls/error.h')
lib.rsa = lib.loadlib('mbedtls','mbedtls/rsa.h')
lib.pk = lib.loadlib('mbedtls','mbedtls/pk.h')
lib.md = lib.loadlib('mbedtls','mbedtls/md.h')
lib.b64 = lib.loadlib('mbedtls','mbedtls/base64.h')
lib.net = lib.loadlib('mongoose','mongoose.h')
lib.pq = lib.loadlib('libpq','libpq-fe.h')
lib.jc = lib.loadlib('json-c','json.h')
lib.load {
'mem', 'math', 'str', 'file', 'crypt', 'ipc';
'http', 'html', 'session', 'tpl', 'store', 'acl';
'smackdown'; -- md-alike parser
}
|
Modified pkgdata.lua from [8c50f1b4b0] to [85c9cc69e8].
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
36
37
|
mbedtls = {
libs = {'mbedtls', 'mbedcrypto', 'mbedx509'};
osvars = {
linux_nixos = { -- lacks a *.pc on nixos systems
prefix = sthunk('nix', 'path-info', 'nixos.mbedtls');
}
};
vars = { builddir = '/library' };
};
mongoose = { vars = { builddir = '' } };
libpq = {
osvars = {
linux_nixos = {
prefix = sthunk('nix', 'path-info', 'nixos.postgresql.lib');
incdir = function()
................................................................................
return (util.exec(a)) .. '/include';
end;
};
};
vars = {pcname = 'postgresql';}
};
libc = {
libs = {'dl'}; -- libc.so does not need explicit mention
osvars = {
linux_nixos = {
prefix = sthunk('nix', 'path-info', 'nixos.glibc');
override = 'glibc';
};
linux = { override = 'glibc'; };
}
};
}
|
|
>
>
>
>
>
>
>
>
>
>
>
|
>
<
|
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
mbedtls = {
libs = {'mbedtls', 'mbedcrypto', 'mbedx509'};
osvars = {
linux_nixos = { -- lacks a *.pc on nixos systems
prefix = sthunk('nix', 'path-info', 'nixos.mbedtls');
}
};
vars = { builddir = '/library', srcincdir = '/include' };
};
['json-c'] = {
osvars = {
linux_nixos = {
prefix = sthunk('nix','path-info','nixos.json_c');
};
};
vars = {
builddir = '';
incsuffix = '/json-c'; -- only used when path generated from prefix
}
};
mongoose = { vars = { builddir = '' } };
libpq = {
osvars = {
linux_nixos = {
prefix = sthunk('nix', 'path-info', 'nixos.postgresql.lib');
incdir = function()
................................................................................
return (util.exec(a)) .. '/include';
end;
};
};
vars = {pcname = 'postgresql';}
};
libc = {
libs = {'c'}; -- libc.so probably does not need explicit mention, but
osvars = {
linux = { override = 'glibc'; };
linux_nixos = {
prefix = sthunk('nix', 'path-info', 'nixos.glibc');
override = 'glibc';
};
}
};
}
|
Modified render/conf/users.t from [be5a9e1656] to [2f981259f7].
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 ... 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 ... 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
:lpush('" max="'):push(lib.math.decstr(max, &decbuf[20]),0)
:lpush('" value="'):push(lib.math.decstr(value, &decbuf[20]),0):lpush('"></div>')
end
end
end)
local input_pusher = function(kind,wrap,uniq)
local fn = terra(acc: &lib.str.acc, name: pstr, val: pstr, lbl: pstr, on: bool, enabled: bool, class: pstr)
if wrap then acc:lpush('<label>') end
acc:lpush(['<input type="'..kind..'" name="']):ppush(name)
if not wrap then
acc:lpush('" id="'):ppush(name)
if uniq then acc:lpush('-'):ppush(val) end
end
if val:ref() then acc:lpush('" value="'):ppush(val) end
if class:ref() then acc:lpush('" class="'):ppush(class) end
acc:lpush('"')
if on then acc:lpush(' checked') end
if not enabled then acc:lpush(' disabled') end
acc:lpush('>')
if not wrap then acc:lpush('<label for="'):ppush(name)
if uniq then acc:lpush('-'):ppush(val) end
acc:lpush('">')
else acc:lpush(' ') end
acc:ppush(lbl):lpush('</label>')
end
fn.name = string.format('push-input-element<%q>',kind)
return fn
................................................................................
push_num_field(cinp, 'quota', 'quota', min, max, user.ptr.rights.quota, user.ptr.id == co.who.id and co.who.rights.rank ~= 1)
end
cinp:lpush('</div><div class="elem"><div class="check-panel">')
if user.ptr.id ~= co.who.id and
((user.ptr.rights.rank == 0 and co.who.rights.powers.elevate()) or
(user.ptr.rights.rank > 0 and co.who.rights.powers.demote())) then
push_checkbox(&cinp, 'staff', pstr.null(), 'site staff member', user.ptr.rights.rank > 0, true, pstr.null())
end
cinp:lpush('</div></div>')
if (co.who.rights.powers.elevate() or
co.who.rights.powers.demote()) and user.ptr.id ~= co.who.id then
var map = array([lib.store.powmap])
................................................................................
for i=0, [map.type.N] do
if (co.who.rights.powers and map[i].val):sz() > 0 then
var on = (user.ptr.rights.powers and map[i].val):sz() > 0
var enabled = ( on and co.who.rights.powers.demote() ) or
((not on) and co.who.rights.powers.elevate())
var namea: lib.str.acc namea:pcompose(&co.srv.pool,'power-', map[i].name)
var name = namea:finalize()
push_pickbox(&cinp, name, pstr.null(), map[i].name, on, enabled, pstr.null())
--name:free()
end
end
cinp:lpush('</div></details>')
end
if co.who.id ~= uid and co.who.rights.powers.purge() then
|
| | | | | |
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 ... 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 ... 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
:lpush('" max="'):push(lib.math.decstr(max, &decbuf[20]),0)
:lpush('" value="'):push(lib.math.decstr(value, &decbuf[20]),0):lpush('"></div>')
end
end
end)
local input_pusher = function(kind,wrap,uniq)
local fn = terra(acc: &lib.str.acc, id: pstr, name: pstr, val: pstr, lbl: pstr, on: bool, enabled: bool, class: pstr)
if wrap then acc:lpush('<label>') end
acc:lpush(['<input type="'..kind..'" name="']):ppush(name)
if not wrap then
acc:lpush('" id="'):ppush(id)
if uniq then acc:lpush('-'):ppush(val) end
end
if val:ref() then acc:lpush('" value="'):ppush(val) end
if class:ref() then acc:lpush('" class="'):ppush(class) end
acc:lpush('"')
if on then acc:lpush(' checked') end
if not enabled then acc:lpush(' disabled') end
acc:lpush('>')
if not wrap then acc:lpush('<label for="'):ppush(id)
if uniq then acc:lpush('-'):ppush(val) end
acc:lpush('">')
else acc:lpush(' ') end
acc:ppush(lbl):lpush('</label>')
end
fn.name = string.format('push-input-element<%q>',kind)
return fn
................................................................................
push_num_field(cinp, 'quota', 'quota', min, max, user.ptr.rights.quota, user.ptr.id == co.who.id and co.who.rights.rank ~= 1)
end
cinp:lpush('</div><div class="elem"><div class="check-panel">')
if user.ptr.id ~= co.who.id and
((user.ptr.rights.rank == 0 and co.who.rights.powers.elevate()) or
(user.ptr.rights.rank > 0 and co.who.rights.powers.demote())) then
push_checkbox(&cinp, 'staff', 'staff', pstr.null(), 'site staff member', user.ptr.rights.rank > 0, true, pstr.null())
end
cinp:lpush('</div></div>')
if (co.who.rights.powers.elevate() or
co.who.rights.powers.demote()) and user.ptr.id ~= co.who.id then
var map = array([lib.store.powmap])
................................................................................
for i=0, [map.type.N] do
if (co.who.rights.powers and map[i].val):sz() > 0 then
var on = (user.ptr.rights.powers and map[i].val):sz() > 0
var enabled = ( on and co.who.rights.powers.demote() ) or
((not on) and co.who.rights.powers.elevate())
var namea: lib.str.acc namea:pcompose(&co.srv.pool,'power-', map[i].name)
var name = namea:finalize()
push_pickbox(&cinp, name, 'power', map[i].name, map[i].name, on, enabled, pstr.null())
--name:free()
end
end
cinp:lpush('</div></details>')
end
if co.who.id ~= uid and co.who.rights.powers.purge() then
|
Modified route.t from [48c04bb947] to [8f0d6bf9b0].
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ... 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 ... 924 925 926 927 928 929 930 931 932 933 934 935 936 937 ... 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 |
var act = co:ppostv('act')
if rel.recip.block() then
if act:cmp('follow') or act:cmp('subscribe') then
co:complain(403,'blocked','you cannot follow a user you are blocked by') return
end
end
if act:cmp('circle') then
lib.dbg('encircling user!')
var allcircs = co.srv:circle_search(&co.srv.pool, co.who.id, 0)
var mycircs = co.srv:circle_memberships_uid(&co.srv.pool, co.who.id, actor.id)
var marked = co.srv.pool:alloc(bool, allcircs.ct)
var member = co.srv.pool:alloc(bool, allcircs.ct)
for i = 0, marked.ct do
marked(i) = false
member(i) = false
................................................................................
handle.ct = uri.ct - 2
uri:advance(uri.ct)
elseif handle.ct + 2 < uri.ct then uri:advance(handle.ct + 2) end
lib.dbg('looking up user by xid "', {handle.ptr,handle.ct} ,'", path: ', {uri.ptr,uri.ct})
var path = lib.http.hier(&co.srv.pool, uri) --defer path:free()
for i=0,path.ct do
lib.dbg('got path component ', {path.ptr[i].ptr, path.ptr[i].ct})
end
var actor = co.srv:actor_fetch_xid(handle)
if actor.ptr == nil then
co:complain(404,'no such user','no such user known to this server')
return
end
defer actor:free()
................................................................................
if not data then goto e404 end
do defer data:free() defer mime:free()
co:bytestream(mime,data)
return end
::e404:: do co:complain(404, 'artifact not found', 'no such artifact has been uploaded to this instance') return 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
-- we run through those first before giving up and parsing the URI
................................................................................
elseif uri:cmp( '/logout') then
if co.aid == 0
then goto notfound
else co:reroute_cookie('/','auth=; Path=/')
end
else -- hierarchical routes
var path = lib.http.hier(&co.srv.pool, uri) --defer path:free()
if path.ct > 1 and path(0):cmp(lib.str.lit('user')) then
http.actor_profile_uid(co, path, meth)
elseif path.ct > 1 and path(0):cmp(lib.str.lit('post')) then
http.tweet_page(co, path, meth)
elseif path(0):cmp(lib.str.lit('tl')) then
http.timeline(co, path)
elseif path(0):cmp(lib.str.lit('media')) then
if co.aid == 0 then goto unauth end
http.media_manager(co, path, meth, co.who.id)
elseif path(0):cmp(lib.str.lit('doc')) then
if not meth_get(meth) then goto wrongmeth end
http.documentation(co, path)
elseif path(0):cmp(lib.str.lit('conf')) then
if co.aid == 0 then goto unauth end
http.configure(co,path,meth)
else goto notfound end
end
do return end
::wrongmeth:: co:complain(405, 'method not allowed', 'that method is not meaningful for this endpoint') do return end
::notfound:: co:complain(404, 'not found', 'no such resource available') do return end
::unauth:: co:complain(401, 'unauthorized', 'this content is not available at your clearance level') do return end
end
|
< < < < > > > > > > | | | > > > > | | | |
17 18 19 20 21 22 23 24 25 26 27 28 29 30 ... 106 107 108 109 110 111 112 113 114 115 116 117 118 119 ... 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 ... 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 |
var act = co:ppostv('act')
if rel.recip.block() then
if act:cmp('follow') or act:cmp('subscribe') then
co:complain(403,'blocked','you cannot follow a user you are blocked by') return
end
end
if act:cmp('circle') then
var allcircs = co.srv:circle_search(&co.srv.pool, co.who.id, 0)
var mycircs = co.srv:circle_memberships_uid(&co.srv.pool, co.who.id, actor.id)
var marked = co.srv.pool:alloc(bool, allcircs.ct)
var member = co.srv.pool:alloc(bool, allcircs.ct)
for i = 0, marked.ct do
marked(i) = false
member(i) = false
................................................................................
handle.ct = uri.ct - 2
uri:advance(uri.ct)
elseif handle.ct + 2 < uri.ct then uri:advance(handle.ct + 2) end
lib.dbg('looking up user by xid "', {handle.ptr,handle.ct} ,'", path: ', {uri.ptr,uri.ct})
var path = lib.http.hier(&co.srv.pool, uri) --defer path:free()
var actor = co.srv:actor_fetch_xid(handle)
if actor.ptr == nil then
co:complain(404,'no such user','no such user known to this server')
return
end
defer actor:free()
................................................................................
if not data then goto e404 end
do defer data:free() defer mime:free()
co:bytestream(mime,data)
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
-- we run through those first before giving up and parsing the URI
................................................................................
elseif uri:cmp( '/logout') then
if co.aid == 0
then goto notfound
else co:reroute_cookie('/','auth=; Path=/')
end
else -- hierarchical routes
var path = lib.http.hier(&co.srv.pool, uri) --defer path:free()
if path.ct > 1 and path(0):cmp('user') then
http.actor_profile_uid(co, path, meth)
elseif path.ct > 1 and path(0):cmp('post') then
http.tweet_page(co, path, meth)
elseif path(0):cmp('tl') then
http.timeline(co, path)
elseif path(0):cmp('.well-known') then
if path(1):cmp('webfinger') then
json.webfinger(co)
end
elseif path(0):cmp('media') then
if co.aid == 0 then goto unauth end
http.media_manager(co, path, meth, co.who.id)
elseif path(0):cmp('doc') then
if not meth_get(meth) then goto wrongmeth end
http.documentation(co, path)
elseif path(0):cmp('conf') then
if co.aid == 0 then goto unauth end
http.configure(co,path,meth)
else goto notfound end
end
do return end
::wrongmeth:: co:complain(405, 'method not allowed', 'that method is not meaningful for this endpoint') do return end
::notfound:: co:complain(404, 'not found', 'no such resource available') do return end
::unauth:: co:complain(401, 'unauthorized', 'this content is not available at your clearance level') do return end
end
|
Modified srv.t from [fbf604f655] to [113b729c73].
304
305
306
307
308
309
310
311
312
313
314
315
316
317
...
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
|
self:rawpage(200, pg, [lib.mem.ptr(lib.http.header)] {
ptr = &hdrs[0], ct = 3
})
end
end
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('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)
var hdrs = array(
lib.http.header { key = 'Content-Type', value = 'text/html; charset=UTF-8' },
lib.http.header { key = 'Location', value = dest },
lib.http.header { key = 'Set-Cookie', value = cookie }
|
>
>
>
>
>
>
>
>
>
>
>
>
|
<
<
|
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
...
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
|
self:rawpage(200, pg, [lib.mem.ptr(lib.http.header)] {
ptr = &hdrs[0], ct = 3
})
end
end
terra convo:stdpage(pg: convo.page) self:statpage(200, pg) end
terra convo:bytestream_trusted(lockdown: bool, mime: pstring, data: lib.mem.ptr(uint8))
var lockhdr = "Content-Security-Policy: sandbox; default-src 'none'; form-action 'none'; navigate-to 'none';\r\n"
if not lockdown then lockhdr = "" end
lib.net.mg_printf(self.con, "HTTP/1.1 200 OK\r\nContent-Type: %.*s\r\nContent-Length: %llu\r\n%sX-Content-Options: nosniff\r\n\r\n", mime.ct, mime.ptr, data.ct + 2, lockdown)
lib.net.mg_send(self.con, data.ptr, data.ct)
lib.net.mg_send(self.con, '\r\n', 2)
end
terra convo:json(data: pstring)
self:bytestream_trusted(false, 'application/ld+json', data:blob())
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('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
self:bytestream_trusted(true, mime, data)
end
terra convo:reroute_cookie(dest: rawstring, cookie: rawstring)
var hdrs = array(
lib.http.header { key = 'Content-Type', value = 'text/html; charset=UTF-8' },
lib.http.header { key = 'Location', value = dest },
lib.http.header { key = 'Set-Cookie', value = cookie }
|