Overview
| Comment: | add in a bunch of missing pqclears, because i am a *retard*, and wipe out a fuckton of memory leaks |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
a4e71fdfda530542a5efa3090ac16dcb |
| User & Date: | lexi on 2021-01-28 02:44:55 |
| Original Comment: | add in a bunch of missing pqclears, because i am a *retards*, and wipe out a fuckton of memory leaks |
| Other Links: | manifest | tags |
Context
|
2021-01-28
| ||
| 02:50 | fix more dumb leaks check-in: 4ce1aab090 user: lexi tags: trunk | |
| 02:44 | add in a bunch of missing pqclears, because i am a *retard*, and wipe out a fuckton of memory leaks check-in: a4e71fdfda user: lexi tags: trunk | |
| 00:51 | wrote mimelib, continued iterating on litepub support; tweets can now be imported into honk check-in: c774e2c5a9 user: lexi tags: trunk | |
Changes
Modified api/lp/outbox.t from [7ed4c4752c] to [748fc8c886].
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 |
var time: lib.store.timepoint
if at:cmp('top') then
time = lib.osclock.time(nil)
else
var tp, ok = lib.math.decparse(at)
if ok then time = tp end
end
lib.io.fmt('from-time: %llu\n', time)
var posts = co.srv:post_enum_author_uid(uid, lib.store.range {
mode = 1; -- time -> idx
from_time = time;
to_idx = 65;
})
var oldest = time
json:lpush',"partOf":"https://':ppush(co.srv.cfg.domain):ppush(path)
:lpush'","type":"CollectionPage","orderedItems":['
if posts.sz > 0 then defer posts:free()
for i=0, lib.math.smallest(posts.sz,64) do
if i~=0 then json:lpush',' end
json:ppush(lib.api.lp.tweet(co,posts(i).ptr,true))
oldest = lib.math.smallest(posts(i)().posted, oldest)
end
end
json:lpush'],"totalItems":':ipush(posts.sz)
if oldest ~= time and oldest > 0 and posts.sz > 64 then
json:lpush',"next":"https://':ppush(co.srv.cfg.domain):ppush(path)
:lpush'?at=':ipush(oldest-1):lpush'"'
end
|
< > |
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 |
var time: lib.store.timepoint
if at:cmp('top') then
time = lib.osclock.time(nil)
else
var tp, ok = lib.math.decparse(at)
if ok then time = tp end
end
var posts = co.srv:post_enum_author_uid(uid, lib.store.range {
mode = 1; -- time -> idx
from_time = time;
to_idx = 65;
})
var oldest = time
json:lpush',"partOf":"https://':ppush(co.srv.cfg.domain):ppush(path)
:lpush'","type":"CollectionPage","orderedItems":['
if posts.sz > 0 then defer posts:free()
for i=0, lib.math.smallest(posts.sz,64) do
if i~=0 then json:lpush',' end
json:ppush(lib.api.lp.tweet(co,posts(i).ptr,true))
oldest = lib.math.smallest(posts(i)().posted, oldest)
posts(i):free()
end
end
json:lpush'],"totalItems":':ipush(posts.sz)
if oldest ~= time and oldest > 0 and posts.sz > 64 then
json:lpush',"next":"https://':ppush(co.srv.cfg.domain):ppush(path)
:lpush'?at=':ipush(oldest-1):lpush'"'
end
|
Modified backend/pgsql.t from [d6c61590d0] to [8e095d7d59].
954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 .... 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 .... 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 .... 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 .... 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 .... 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 .... 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 .... 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 .... 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 .... 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 .... 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 .... 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 .... 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 .... 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 .... 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 .... 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 |
-- only to the connecting parsav instance, stored in memory, and dropped
-- as soon as the connection session ends.
local tempviews = sqlsquash(lib.util.ingest 'backend/schema/pgsql-views.sql')
local prep = { quote
var res = lib.pq.PQexec([con], tempviews)
if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
lib.dbg('uploading pgsql session views')
else
lib.bail('backend pgsql - failed to upload session views: \n', lib.pq.PQresultErrorMessage(res))
end
end }
for k,q in pairs(queries) do
local qt = sqlsquash(q.sql)
................................................................................
[#args], params, params_sz, params_ft, 1)
if res == nil then
lib.bail(['grievous error occurred executing '..k..' against database'])
elseif lib.pq.PQresultStatus(res) ~= okconst then
lib.bail(['PGSQL database procedure '..k..' failed\n'],
lib.pq.PQresultErrorMessage(res))
end
var ct = lib.pq.PQntuples(res)
if ct == 0 then
lib.pq.PQclear(res)
return pqr {0, nil}
else
return pqr {ct, res}
end
end
q.exec.name = 'pgsql.' .. k .. '.exec'
end
local terra row_to_artifact(res: &pqr, i: intptr): lib.mem.ptr(lib.store.artifact)
var id = res:int(uint64,i,0)
................................................................................
local getpow = terra(
src: &lib.store.source,
uid: uint64
): lib.store.powerset
var powers = lib.store.rights_default().powers
var map = array([privmap])
var r = queries.actor_powers_fetch.exec(src, uid)
for i=0, r.sz do
for j=0, [map.type.N] do
var pn = r:_string(i,0)
if map[j].name:cmp(pn) then
if r:bool(i,1)
then powers = powers + map[j].val
................................................................................
return powers
end
local txdo = terra(src: &lib.store.source)
var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), 'begin')
if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
lib.dbg('beginning pgsql transaction')
return true
else
lib.warn('backend pgsql - failed to begin transaction: \n', lib.pq.PQresultErrorMessage(res))
return false
end
end
local txdone = terra(src: &lib.store.source)
var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), 'end')
if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
lib.dbg('completing pgsql transaction')
return true
else
lib.warn('backend pgsql - failed to complete transaction: \n', lib.pq.PQresultErrorMessage(res))
return false
end
end
local b = `lib.store.backend {
id = "pgsql";
open = [terra(src: &lib.store.source): &opaque
lib.report('connecting to postgres database: ', src.string.ptr)
var [con] = lib.pq.PQconnectdb(src.string.ptr)
................................................................................
key: binblob
): {}
queries.server_setup_self.exec(src,domain,key,lib.osclock.time(nil))
end];
dbsetup = [terra(src: &lib.store.source): bool
var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), schema)
if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
lib.report('successfully instantiated schema in database')
return true
else
lib.warn('backend pgsql - failed to initialize database: \n', lib.pq.PQresultErrorMessage(res))
return false
end
end];
obliterate_everything = [terra(src: &lib.store.source): bool
var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), obliterator)
if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
lib.report('successfully wiped out everything parsav-related in database')
return true
else
lib.warn('backend pgsql - failed to obliterate database: \n', lib.pq.PQresultErrorMessage(res))
return false
end
end];
conf_get = [terra(src: &lib.store.source, key: pstring)
var r = queries.conf_get.exec(src, key)
if r.sz == 0 then return [lib.mem.ptr(int8)] { ptr = nil, ct = 0 } else
defer r:free()
return r:String(0,0)
end
end];
conf_set = [terra(src: &lib.store.source, key: pstring, val: pstring)
queries.conf_set.exec(src, key, val):free() end];
conf_reset = [terra(src: &lib.store.source, key: rawstring)
queries.conf_reset.exec(src, key):free() end];
actor_fetch_uid = [terra(src: &lib.store.source, uid: uint64)
var r = queries.actor_fetch_uid.exec(src, uid)
if r.sz == 0 then
return [lib.mem.ptr(lib.store.actor)] { ct = 0, ptr = nil }
else defer r:free()
var a = row_to_actor(&r, 0)
................................................................................
::fail::return 0, 0, pstring.null()
end];
actor_stats = [terra(src: &lib.store.source, uid: uint64)
var r = queries.actor_stats.exec(src, uid)
if r.sz == 0 then lib.bail('error fetching actor stats!') end
var s: lib.store.actor_stats
s.posts = r:int(uint64, 0, 0)
s.follows = r:int(uint64, 0, 1)
s.followers = r:int(uint64, 0, 2)
s.mutuals = r:int(uint64, 0, 3)
return s
end];
................................................................................
post_fetch = [terra(
src: &lib.store.source,
post: uint64
): lib.mem.ptr(lib.store.post)
var r = queries.post_fetch.exec(src, post)
if r.sz == 0 then return [lib.mem.ptr(lib.store.post)].null() end
var p = row_to_post(&r, 0)
p.ptr.source = src
return p
end];
post_act_cancel = [terra(
src: &lib.store.source,
................................................................................
r = queries.timeline_instance_fetch.exec(src,A,B,C,D)
var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
for i=0,r.sz do
ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL
ret.ptr[i].ptr.source = src
end
return ret
end];
timeline_circle_fetch = [terra(
src: &lib.store.source,
cid: uint64,
................................................................................
r = queries.timeline_circle_fetch.exec(src,cid,A,B,C,D)
var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
for i=0,r.sz do
ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL
ret.ptr[i].ptr.source = src
end
return ret
end];
timeline_actor_fetch_uid = [terra(
src: &lib.store.source,
uid: uint64,
................................................................................
r = queries.timeline_actor_fetch.exec(src,uid,A,B,C,D)
var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
for i=0,r.sz do
ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL
ret.ptr[i].ptr.source = src
end
return ret
end];
post_enum_author_uid = [terra(
src: &lib.store.source,
uid: uint64,
................................................................................
r = queries.post_enum_author_uid.exec(src,A,B,C,D,uid)
var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
for i=0,r.sz do
ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL
ret.ptr[i].ptr.source = src
end
return ret
end];
actor_powers_fetch = getpow;
actor_save = [terra(
src: &lib.store.source,
................................................................................
ac.id = r:int(uint64,0,0)
-- check against default rights, insert records for wherever powers differ
lib.dbg('created new actor, establishing powers')
privupdate(src,ac)
lib.dbg('powers established')
return ac.id
end];
actor_rel_create = [terra(
src: &lib.store.source,
kind: uint16,
relator: uint64,
................................................................................
auth_fetch_aid = [terra(
src: &lib.store.source,
aid: uint64
): lib.mem.ptr(lib.store.auth)
var r = queries.auth_fetch_aid.exec(src,aid)
if r.sz == 0 then return [lib.mem.ptr(lib.store.auth)].null() end
var kind = r:_string(0, 2)
var comment = r:_string(0, 3)
var a = [ lib.str.encapsulate(lib.store.auth, {
kind = {`kind.ptr, `kind.ct+1};
comment = {`comment.ptr, `comment.ct+1};
}) ]
a.ptr.aid = r:int(uint64, 0, 0)
................................................................................
auth_enum_uid = [terra(
src: &lib.store.source,
uid: uint64
): lib.mem.lstptr(lib.store.auth)
var r = queries.auth_enum_uid.exec(src,uid)
if r.sz == 0 then return [lib.mem.lstptr(lib.store.auth)].null() end
var ret = lib.mem.heapa([lib.mem.ptr(lib.store.auth)], r.sz)
for i=0, r.sz do
var kind = r:_string(i, 1)
var comment = r:_string(i, 2)
var a = [ lib.str.encapsulate(lib.store.auth, {
kind = {`kind.ptr, `kind.ct+1};
comment = {`comment.ptr, `comment.ct+1};
................................................................................
artifact_enum_uid = [terra(
src: &lib.store.source,
uid: uint64,
folder: pstring
)
var res = queries.artifact_enum_uid.exec(src,uid,folder)
if res.sz > 0 then
var m = lib.mem.heapa([lib.mem.ptr(lib.store.artifact)], res.sz)
for i=0,res.sz do
m.ptr[i] = row_to_artifact(&res, i)
m(i).ptr.owner = uid
end
return m
else return [lib.mem.lstptr(lib.store.artifact)].null() end
................................................................................
actor_conf_str_enum = nil;
actor_conf_str_get = [terra(
src: &lib.store.source,
pool: &lib.mem.pool,
uid: uint64,
key: pstring
): pstring
var r = queries.actor_conf_str_get.exec(src, uid, key)
if r.sz > 0 then
return r:_string(0,0):pdup(pool)
else return pstring.null() end
end];
actor_conf_str_set = [terra(src: &lib.store.source, uid: uint64, key: pstring, value: pstring): {}
queries.actor_conf_str_set.exec(src,uid,key,value) end];
actor_conf_str_reset = [terra(src: &lib.store.source, uid: uint64, key: pstring): {}
queries.actor_conf_str_reset.exec(src,uid,key) end];
actor_conf_int_enum = nil;
actor_conf_int_get = [terra(src: &lib.store.source, uid: uint64, key: pstring)
var r = queries.actor_conf_int_get.exec(src, uid, key)
if r.sz > 0 then
var ret = r:int(uint64,0,0)
r:free()
|
| > < > > > > | | | | | | > > > > | | > > > | | > > > < | > > > < > > | | | | > > > > > > > > > | | | | | | | | |
954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 .... 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 .... 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 .... 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 .... 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 .... 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 .... 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 .... 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 .... 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 .... 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 .... 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 .... 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 .... 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 .... 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 .... 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 .... 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 |
-- only to the connecting parsav instance, stored in memory, and dropped
-- as soon as the connection session ends.
local tempviews = sqlsquash(lib.util.ingest 'backend/schema/pgsql-views.sql')
local prep = { quote
var res = lib.pq.PQexec([con], tempviews)
if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
lib.dbg('uploaded pgsql session views')
lib.pq.PQclear(res)
else
lib.bail('backend pgsql - failed to upload session views: \n', lib.pq.PQresultErrorMessage(res))
end
end }
for k,q in pairs(queries) do
local qt = sqlsquash(q.sql)
................................................................................
[#args], params, params_sz, params_ft, 1)
if res == nil then
lib.bail(['grievous error occurred executing '..k..' against database'])
elseif lib.pq.PQresultStatus(res) ~= okconst then
lib.bail(['PGSQL database procedure '..k..' failed\n'],
lib.pq.PQresultErrorMessage(res))
end
escape
if q.cmd then
emit quote lib.pq.PQclear(res) end
else emit quote
var ct = lib.pq.PQntuples(res)
if ct == 0 then
lib.pq.PQclear(res)
return pqr {0, nil}
else
return pqr {ct, res}
end
end end
end
end
q.exec.name = 'pgsql.' .. k .. '.exec'
end
local terra row_to_artifact(res: &pqr, i: intptr): lib.mem.ptr(lib.store.artifact)
var id = res:int(uint64,i,0)
................................................................................
local getpow = terra(
src: &lib.store.source,
uid: uint64
): lib.store.powerset
var powers = lib.store.rights_default().powers
var map = array([privmap])
var r = queries.actor_powers_fetch.exec(src, uid)
defer r:free()
for i=0, r.sz do
for j=0, [map.type.N] do
var pn = r:_string(i,0)
if map[j].name:cmp(pn) then
if r:bool(i,1)
then powers = powers + map[j].val
................................................................................
return powers
end
local txdo = terra(src: &lib.store.source)
var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), 'begin')
var r: bool
if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
lib.dbg('beginning pgsql transaction')
r = true
else
lib.warn('backend pgsql - failed to begin transaction: \n', lib.pq.PQresultErrorMessage(res))
r = false
end
lib.pq.PQclear(res)
return r
end
local txdone = terra(src: &lib.store.source)
var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), 'end')
var r: bool
if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
lib.dbg('completing pgsql transaction')
r = true
else
lib.warn('backend pgsql - failed to complete transaction: \n', lib.pq.PQresultErrorMessage(res))
r = false
end
lib.pq.PQclear(res)
return r
end
local b = `lib.store.backend {
id = "pgsql";
open = [terra(src: &lib.store.source): &opaque
lib.report('connecting to postgres database: ', src.string.ptr)
var [con] = lib.pq.PQconnectdb(src.string.ptr)
................................................................................
key: binblob
): {}
queries.server_setup_self.exec(src,domain,key,lib.osclock.time(nil))
end];
dbsetup = [terra(src: &lib.store.source): bool
var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), schema)
var r = true
if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
lib.report('successfully instantiated schema in database')
else
lib.warn('backend pgsql - failed to initialize database: \n', lib.pq.PQresultErrorMessage(res))
r = false
end
lib.pq.PQclear(res)
return r
end];
obliterate_everything = [terra(src: &lib.store.source): bool
var res = lib.pq.PQexec([&lib.pq.PGconn](src.handle), obliterator)
var r = true
if lib.pq.PQresultStatus(res) == lib.pq.PGRES_COMMAND_OK then
lib.report('successfully wiped out everything parsav-related in database')
else
lib.warn('backend pgsql - failed to obliterate database: \n', lib.pq.PQresultErrorMessage(res))
return false
end
lib.pq.PQclear(res)
return r
end];
conf_get = [terra(src: &lib.store.source, pool: &lib.mem.pool, key: pstring)
var r = queries.conf_get.exec(src, key)
if r.sz == 0 then return [lib.mem.ptr(int8)] { ptr = nil, ct = 0 } else
defer r:free()
return r:_string(0,0):pdup(pool)
end
end];
conf_set = [terra(src: &lib.store.source, key: pstring, val: pstring)
queries.conf_set.exec(src, key, val) end];
conf_reset = [terra(src: &lib.store.source, key: rawstring)
queries.conf_reset.exec(src, key) end];
actor_fetch_uid = [terra(src: &lib.store.source, uid: uint64)
var r = queries.actor_fetch_uid.exec(src, uid)
if r.sz == 0 then
return [lib.mem.ptr(lib.store.actor)] { ct = 0, ptr = nil }
else defer r:free()
var a = row_to_actor(&r, 0)
................................................................................
::fail::return 0, 0, pstring.null()
end];
actor_stats = [terra(src: &lib.store.source, uid: uint64)
var r = queries.actor_stats.exec(src, uid)
if r.sz == 0 then lib.bail('error fetching actor stats!') end
defer r:free()
var s: lib.store.actor_stats
s.posts = r:int(uint64, 0, 0)
s.follows = r:int(uint64, 0, 1)
s.followers = r:int(uint64, 0, 2)
s.mutuals = r:int(uint64, 0, 3)
return s
end];
................................................................................
post_fetch = [terra(
src: &lib.store.source,
post: uint64
): lib.mem.ptr(lib.store.post)
var r = queries.post_fetch.exec(src, post)
if r.sz == 0 then return [lib.mem.ptr(lib.store.post)].null() end
defer r:free()
var p = row_to_post(&r, 0)
p.ptr.source = src
return p
end];
post_act_cancel = [terra(
src: &lib.store.source,
................................................................................
r = queries.timeline_instance_fetch.exec(src,A,B,C,D)
var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
for i=0,r.sz do
ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL
ret.ptr[i].ptr.source = src
end
r:free()
return ret
end];
timeline_circle_fetch = [terra(
src: &lib.store.source,
cid: uint64,
................................................................................
r = queries.timeline_circle_fetch.exec(src,cid,A,B,C,D)
var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
for i=0,r.sz do
ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL
ret.ptr[i].ptr.source = src
end
r:free()
return ret
end];
timeline_actor_fetch_uid = [terra(
src: &lib.store.source,
uid: uint64,
................................................................................
r = queries.timeline_actor_fetch.exec(src,uid,A,B,C,D)
var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
for i=0,r.sz do
ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL
ret.ptr[i].ptr.source = src
end
r:free()
return ret
end];
post_enum_author_uid = [terra(
src: &lib.store.source,
uid: uint64,
................................................................................
r = queries.post_enum_author_uid.exec(src,A,B,C,D,uid)
var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
for i=0,r.sz do
ret.ptr[i] = row_to_post(&r, i) -- MUST FREE ALL
ret.ptr[i].ptr.source = src
end
r:free()
return ret
end];
actor_powers_fetch = getpow;
actor_save = [terra(
src: &lib.store.source,
................................................................................
ac.id = r:int(uint64,0,0)
-- check against default rights, insert records for wherever powers differ
lib.dbg('created new actor, establishing powers')
privupdate(src,ac)
lib.dbg('powers established')
r:free()
return ac.id
end];
actor_rel_create = [terra(
src: &lib.store.source,
kind: uint16,
relator: uint64,
................................................................................
auth_fetch_aid = [terra(
src: &lib.store.source,
aid: uint64
): lib.mem.ptr(lib.store.auth)
var r = queries.auth_fetch_aid.exec(src,aid)
if r.sz == 0 then return [lib.mem.ptr(lib.store.auth)].null() end
defer r:free()
var kind = r:_string(0, 2)
var comment = r:_string(0, 3)
var a = [ lib.str.encapsulate(lib.store.auth, {
kind = {`kind.ptr, `kind.ct+1};
comment = {`comment.ptr, `comment.ct+1};
}) ]
a.ptr.aid = r:int(uint64, 0, 0)
................................................................................
auth_enum_uid = [terra(
src: &lib.store.source,
uid: uint64
): lib.mem.lstptr(lib.store.auth)
var r = queries.auth_enum_uid.exec(src,uid)
if r.sz == 0 then return [lib.mem.lstptr(lib.store.auth)].null() end
defer r:free()
var ret = lib.mem.heapa([lib.mem.ptr(lib.store.auth)], r.sz)
for i=0, r.sz do
var kind = r:_string(i, 1)
var comment = r:_string(i, 2)
var a = [ lib.str.encapsulate(lib.store.auth, {
kind = {`kind.ptr, `kind.ct+1};
comment = {`comment.ptr, `comment.ct+1};
................................................................................
artifact_enum_uid = [terra(
src: &lib.store.source,
uid: uint64,
folder: pstring
)
var res = queries.artifact_enum_uid.exec(src,uid,folder)
if res.sz > 0 then defer res:free()
var m = lib.mem.heapa([lib.mem.ptr(lib.store.artifact)], res.sz)
for i=0,res.sz do
m.ptr[i] = row_to_artifact(&res, i)
m(i).ptr.owner = uid
end
return m
else return [lib.mem.lstptr(lib.store.artifact)].null() end
................................................................................
actor_conf_str_enum = nil;
actor_conf_str_get = [terra(
src: &lib.store.source,
pool: &lib.mem.pool,
uid: uint64,
key: pstring
): pstring
var r = queries.actor_conf_str_get.exec(src, uid, key)
if r.sz > 0 then defer r:free()
return r:_string(0,0):pdup(pool)
else return pstring.null() end
end];
actor_conf_str_set = [terra(src: &lib.store.source, uid: uint64, key: pstring, value: pstring): {}
queries.actor_conf_str_set.exec(src,uid,key,value) end];
actor_conf_str_reset = [terra(src: &lib.store.source, uid: uint64, key: pstring): {}
queries.actor_conf_str_reset.exec(src,uid,key) end];
actor_conf_int_enum = nil;
actor_conf_int_get = [terra(src: &lib.store.source, uid: uint64, key: pstring)
var r = queries.actor_conf_int_get.exec(src, uid, key)
if r.sz > 0 then
var ret = r:int(uint64,0,0)
r:free()
|
Modified convo.t from [ff68c1adfe] to [5c6e342d23].
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
method: lib.http.method.t
live_last: lib.store.timepoint
uploads: lib.mem.vec(lib.http.upload)
body: pstring
-- cache
ui_hue: uint16
navbar: pstring
actorcache: lib.mem.cache(lib.mem.ptr(lib.store.actor),32) -- naive cache to avoid unnecessary queries
-- private
varbuf: pstring
vbofs: &int8
}
struct convo.page {
title: pstring
|
| |
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
method: lib.http.method.t
live_last: lib.store.timepoint
uploads: lib.mem.vec(lib.http.upload)
body: pstring
-- cache
ui_hue: uint16
navbar: pstring
actorcache: lib.mem.cache(lib.mem.ptr(lib.store.actor),32,true) -- naive cache to avoid unnecessary queries
-- private
varbuf: pstring
vbofs: &int8
}
struct convo.page {
title: pstring
|
Modified mem.t from [d10508934e] to [8aa8839430].
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
..
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
local p = m.ptr(ty:astype())
return `p {
ptr = [&ty:astype()](m.heapa_raw(sizeof(ty) * sz));
ct = sz;
}
end)
function m.cache(ty,sz)
sz = sz or 32
local struct c {
store: ty[sz]
top: intptr
cur: intptr
}
c.name = string.format('cache<%s,%u>', tostring(ty), sz)
................................................................................
end
self.store[self.cur] = v
self.top = lib.math.biggest(self.top, self.cur + 1)
self.cur = (self.cur + 1) % sz
return v
end
c.metamethods.__apply = terra(self: &c, idx: intptr) return &self.store[idx] end
if ty.ptr_basetype then
terra c:free()
for i=0,self.top do self.store[i]:free() end
end
end
return c
end
|
|
|
|
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
..
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
local p = m.ptr(ty:astype())
return `p {
ptr = [&ty:astype()](m.heapa_raw(sizeof(ty) * sz));
ct = sz;
}
end)
function m.cache(ty,sz,autofree)
sz = sz or 32
local struct c {
store: ty[sz]
top: intptr
cur: intptr
}
c.name = string.format('cache<%s,%u>', tostring(ty), sz)
................................................................................
end
self.store[self.cur] = v
self.top = lib.math.biggest(self.top, self.cur + 1)
self.cur = (self.cur + 1) % sz
return v
end
c.metamethods.__apply = terra(self: &c, idx: intptr) return &self.store[idx] end
if autofree then
terra c:free()
for i=0,self.top do self.store[i]:free() end
end
end
return c
end
|
Modified mgtool.t from [aa223ca2fb] to [f2643e6a8b].
54 55 56 57 58 59 60 61 62 63 64 65 66 67 .. 74 75 76 77 78 79 80 81 82 83 84 85 86 87 ... 155 156 157 158 159 160 161 162 163 164 165 166 167 168 ... 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 |
all: bool
src: &lib.store.source
srv: &lib.srv.overlord
sid: uint64
iname: rawstring
}
idelegate.metamethods.__methodmissing = macro(function(meth, self, ...)
local expr = {...}
local rt
for _,f in pairs(lib.store.backend.entries) do
local fn = f.field or f[1]
................................................................................
if self.all or (self.srv ~= nil and self.srv.sources.ct == 1)
then r=self.srv:[meth]([expr])
elseif self.src ~= nil then r=self.src:[meth]([expr])
else lib.bail('no data source specified')
end
in r end
end)
terra idelegate:ipc_send(cmd: lib.ipc.cmd.t, operand: uint64)
var emp = self.emperor
var acks: lib.mem.ptr(lib.ipc.ack)
if self.sid == 0 and self.iname == nil then
if not self.all and emp:countpeers() > 1 then
lib.bail('either specify the instance to control or pass --all to control all instances')
................................................................................
[lib.init]
var srv: lib.srv.overlord
var dlg = idelegate {
emperor = &emp, srv = &srv;
src = nil, sid = 0, iname = nil, all = false;
}
var mode: ctloptions
mode:parse(argc,argv) defer mode:free()
if mode.version then version() return 0 end
if mode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' ', ctloptions.helptxt.flags, ' <cmd> [<args>…]', ctloptions.helptxt.opts, cmdhelp(ctlcmds)) ]
return 0
................................................................................
if lib.str.cmp(mode.arglist(0),'mkroot') == 0 then
var cfmode: pbasic cfmode:parse(mode.arglist.ct, &mode.arglist(0))
if cfmode.help then
[ lib.emit(false, 1, 'usage: ', `argv[0], ' mkroot ', cfmode.type.helptxt.flags, ' <handle>', cfmode.type.helptxt.opts) ]
return 1
end
if cfmode.arglist.ct == 1 then
var am = dlg:conf_get('credential-store')
var mg: bool
if (not am) or am:cmp('managed') then
mg = true
elseif am:cmp('unmanaged') then
lib.warn('credential store is unmanaged; you will need to create credentials for the new root user manually!')
mg = false
else lib.bail('unknown credential store mode "',{am.ptr,am.ct},'"; should be either "managed" or "unmanaged"') end
|
> > > > > > > | |
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 .. 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 ... 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 ... 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
all: bool src: &lib.store.source srv: &lib.srv.overlord sid: uint64 iname: rawstring cfgpool: lib.mem.pool } idelegate.metamethods.__methodmissing = macro(function(meth, self, ...) local expr = {...} local rt for _,f in pairs(lib.store.backend.entries) do local fn = f.field or f[1] ................................................................................ if self.all or (self.srv ~= nil and self.srv.sources.ct == 1) then r=self.srv:[meth]([expr]) elseif self.src ~= nil then r=self.src:[meth]([expr]) else lib.bail('no data source specified') end in r end end) terra idelegate:conf(key: lib.str.t) return self:conf_get(&self.cfgpool, key) end terra idelegate:ipc_send(cmd: lib.ipc.cmd.t, operand: uint64) var emp = self.emperor var acks: lib.mem.ptr(lib.ipc.ack) if self.sid == 0 and self.iname == nil then if not self.all and emp:countpeers() > 1 then lib.bail('either specify the instance to control or pass --all to control all instances') ................................................................................ [lib.init] var srv: lib.srv.overlord var dlg = idelegate { emperor = &emp, srv = &srv; src = nil, sid = 0, iname = nil, all = false; } dlg.cfgpool:init(128) var mode: ctloptions mode:parse(argc,argv) defer mode:free() if mode.version then version() return 0 end if mode.help then [ lib.emit(false, 1, 'usage: ', `argv[0], ' ', ctloptions.helptxt.flags, ' <cmd> [<args>…]', ctloptions.helptxt.opts, cmdhelp(ctlcmds)) ] return 0 ................................................................................ if lib.str.cmp(mode.arglist(0),'mkroot') == 0 then var cfmode: pbasic cfmode:parse(mode.arglist.ct, &mode.arglist(0)) if cfmode.help then [ lib.emit(false, 1, 'usage: ', `argv[0], ' mkroot ', cfmode.type.helptxt.flags, ' <handle>', cfmode.type.helptxt.opts) ] return 1 end if cfmode.arglist.ct == 1 then var am = dlg:conf('credential-store') var mg: bool if (not am) or am:cmp('managed') then mg = true elseif am:cmp('unmanaged') then lib.warn('credential store is unmanaged; you will need to create credentials for the new root user manually!') mg = false else lib.bail('unknown credential store mode "',{am.ptr,am.ct},'"; should be either "managed" or "unmanaged"') end |
Modified mime.t from [8a0a5cf230] to [16ec90c72f].
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
..
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
if type(ty.id) == 'string' then ty.id = {ty.id} end
for i, mime in ipairs(ty.id) do
idcache[mime] = ty
end
local op = lib.http.mime[typecode]
if op == nil then op = lib.http.mime.none end
print(typecode,op)
ty.offset = #typestore
typestore[#typestore + 1] = `mime {
key = typecode;
canonical = [ty.id[1]];
safe = [not ty.unsafe];
ext = [ty.ext or `pstr{nil,0}];
................................................................................
type = mime;
types = knowntypes;
tbl = idcache;
typedex = typedex;
lookup = terra(m: pstr): &mime
for i=0, [#typemap_l] do
if m:cmp(typemap[i].string) then
lib.io.fmt('returning type %s %u\n', typemap[i].type.key, typemap[i].type.output)
return typemap[i].type
end
end
return nil
end;
}
|
<
<
|
56
57
58
59
60
61
62
63
64
65
66
67
68
69
..
95
96
97
98
99
100
101
102
103
104
105
106
107
|
if type(ty.id) == 'string' then ty.id = {ty.id} end
for i, mime in ipairs(ty.id) do
idcache[mime] = ty
end
local op = lib.http.mime[typecode]
if op == nil then op = lib.http.mime.none end
ty.offset = #typestore
typestore[#typestore + 1] = `mime {
key = typecode;
canonical = [ty.id[1]];
safe = [not ty.unsafe];
ext = [ty.ext or `pstr{nil,0}];
................................................................................
type = mime;
types = knowntypes;
tbl = idcache;
typedex = typedex;
lookup = terra(m: pstr): &mime
for i=0, [#typemap_l] do
if m:cmp(typemap[i].string) then
return typemap[i].type
end
end
return nil
end;
}
|
Modified parsav.t from [3c7c1240d3] to [584b173afe].
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 |
elseif d.cmd == lib.ipc.cmd.enumerate then
if srv.id ~= nil then
lib.str.ncpy(&a.iname[0], srv.id, [(`a.iname).tree.type.N])
else a.iname[0] = 0 end
elseif d.cmd == lib.ipc.cmd.chnoise then
lib.noise.level = d.operand
elseif d.cmd == lib.ipc.cmd.cfgrefresh then
srv.cfg:free()
srv.cfg:load()
end
d:ack(&lib.ipc.global_emperor, &a)
end
end
srv:shutdown()
|
| |
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 |
elseif d.cmd == lib.ipc.cmd.enumerate then
if srv.id ~= nil then
lib.str.ncpy(&a.iname[0], srv.id, [(`a.iname).tree.type.N])
else a.iname[0] = 0 end
elseif d.cmd == lib.ipc.cmd.chnoise then
lib.noise.level = d.operand
elseif d.cmd == lib.ipc.cmd.cfgrefresh then
srv.cfg:purge()
srv.cfg:load()
end
d:ack(&lib.ipc.global_emperor, &a)
end
end
srv:shutdown()
|
Modified route.t from [1bb0eb41f3] to [5d2607bf9b].
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
...
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
|
return quote
var [me]
[check]
in [me] end
end)()]
if privs:sz() > 0 then
lib.dbg('installing credential restrictions')
lib.io.fmt('on priv %llu\n',aid)
co.srv:auth_privs_set(aid, privs)
end
lib.dbg('setting netmask restrictions')
var nm = co:pgetv('netmask')
end
co:reroute('?')
................................................................................
end
end
terra http.local_avatar(co: &lib.srv.convo, handle: lib.mem.ptr(int8))
-- TODO retrieve user avatars
var usr = co.srv:actor_fetch_xid(handle)
if not usr then
goto default end
if usr(0).origin == 0 then
if usr(0).avatarid == 0 then goto default end
var avi, mime = co.srv:artifact_load(usr(0).avatarid)
if not avi then goto default end
defer avi:free() defer mime:free()
co:bytestream(mime,avi)
else
co:reroute(usr(0).avatar)
end
do return end
::default:: co:reroute('/s/default-avatar.webp')
end
terra http.file_serve_raw(co: &lib.srv.convo, id: lib.mem.ptr(int8))
var id, idok = lib.math.shorthand.parse(id.ptr, id.ct)
if not idok then goto e404 end
var data, mime = co.srv:artifact_load(id)
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
517
518
519
520
521
522
523
524
525
526
527
528
529
530
...
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
|
return quote
var [me]
[check]
in [me] end
end)()]
if privs:sz() > 0 then
lib.dbg('installing credential restrictions')
co.srv:auth_privs_set(aid, privs)
end
lib.dbg('setting netmask restrictions')
var nm = co:pgetv('netmask')
end
co:reroute('?')
................................................................................
end
end
terra http.local_avatar(co: &lib.srv.convo, handle: lib.mem.ptr(int8))
-- TODO retrieve user avatars
var usr = co.srv:actor_fetch_xid(handle)
if not usr then goto default end
do defer usr:free()
if usr(0).origin == 0 then
if usr(0).avatarid == 0 then goto default end
var avi, mime = co.srv:artifact_load(usr(0).avatarid)
if not avi then goto default end
defer avi:free() defer mime:free()
co:bytestream(mime,avi)
else
co:reroute(usr(0).avatar)
end
return end
::default:: co:reroute('/s/default-avatar.webp')
end
terra http.file_serve_raw(co: &lib.srv.convo, id: lib.mem.ptr(int8))
var id, idok = lib.math.shorthand.parse(id.ptr, id.ct)
if not idok then goto e404 end
var data, mime = co.srv:artifact_load(id)
|
Modified session.t from [c79e9ffb10] to [15e824caf3].
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
[lib.mem.ptr(uint8)] {ptr = [&uint8](secret.ptr), ct = secret.ct},
[lib.mem.ptr( int8)] {ptr = out, ct = len},
&hash[0])
ptr = ptr + lib.math.shorthand.gen(lib.math.truncate64(hash, [hash.type.N]), ptr)
return ptr - out
end
terra m.cookie_interpret(secret: lib.mem.ptr(int8), c: lib.mem.ptr(int8), now: uint64) -- returns either 0,0 or a valid {authid, timepoint}
var authid_sz = lib.str.cspan(c.ptr, lib.str.lit '.', c.ct)
if authid_sz == 0 then return 0,0 end
if authid_sz + 1 > c.ct then return 0,0 end
var time_sz = lib.str.cspan(c.ptr+authid_sz+1, lib.str.lit '.', c.ct - (authid_sz+1))
if time_sz == 0 then return 0,0 end
if (authid_sz + time_sz + 2) > c.ct then return 0,0 end
var hash_sz = c.ct - (authid_sz + time_sz + 2)
var knownhash: uint8[lib.crypt.algsz.sha256]
lib.crypt.hmac(lib.crypt.alg.sha256,
[lib.mem.ptr(uint8)] {ptr = [&uint8](secret.ptr), ct = secret.ct},
|
| > | | |
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
[lib.mem.ptr(uint8)] {ptr = [&uint8](secret.ptr), ct = secret.ct},
[lib.mem.ptr( int8)] {ptr = out, ct = len},
&hash[0])
ptr = ptr + lib.math.shorthand.gen(lib.math.truncate64(hash, [hash.type.N]), ptr)
return ptr - out
end
terra m.cookie_interpret(secret: lib.mem.ptr(int8), c: lib.mem.ptr(int8), now: uint64)
-- returns either 0,0 or a valid {authid, timepoint}
var authid_sz = lib.str.cspan(c.ptr, '.', c.ct)
if authid_sz == 0 then return 0,0 end
if authid_sz + 1 > c.ct then return 0,0 end
var time_sz = lib.str.cspan(c.ptr+authid_sz+1, '.', c.ct - (authid_sz+1))
if time_sz == 0 then return 0,0 end
if (authid_sz + time_sz + 2) > c.ct then return 0,0 end
var hash_sz = c.ct - (authid_sz + time_sz + 2)
var knownhash: uint8[lib.crypt.algsz.sha256]
lib.crypt.hmac(lib.crypt.alg.sha256,
[lib.mem.ptr(uint8)] {ptr = [&uint8](secret.ptr), ct = secret.ct},
|
Modified srv.t from [dafa2dc374] to [1938b717c7].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 .. 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 ... 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 ... 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 ... 654 655 656 657 658 659 660 661 662 663 664 665 666 667 ... 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 ... 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 ... 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 |
-- vim: ft=terra
local util = lib.util
local secmode = lib.enum { 'public', 'private', 'lockdown', 'isolate' }
local pstring = lib.mem.ptr(int8)
local struct srv
local struct cfgcache {
secret: pstring
pol_sec: secmode.t
pol_reg: bool
pol_autoherald: bool
credmgd: bool
maxupsz: intptr
poolinitsz: intptr
................................................................................
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))
var all: lib.mem.vec(lib.mem.ptr(lib.store.post)) all:init(64)
for i=0,self.sources.ct do var src = self.sources.ptr + i
if src.handle ~= nil and src.backend.timeline_instance_fetch ~= nil then
var lst = src:post_enum_author_uid(uid,r)
................................................................................
co:complain(400,'bad request','unrecognized content-type')
goto fail
end
var boundary = pstring {ptr=p+9,ct=ctt.ct - ((p - ctt.ptr) + 9)}
co.method = lib.http.method.post_file
co.uploads:init(8)
var bsr = (lib.str.acc{}):compose('\r\n--',boundary,'\r\n'):finalize()
var upmap = lib.str.splitmap(co.body,bsr,8)
-- first entry may not be preceded by header-break
if lib.str.find(upmap(0), pstring {
ptr = bsr.ptr + 2, ct = bsr.ct - 2
}):ref() then
upmap(0).ptr = upmap(0).ptr + (bsr.ct - 2)
................................................................................
nextup.field = fld
nextup.filename = file
end
end
end
end
end
bsr:free()
upmap:free()
end
end
end
var mtt = lib.http.mime._str(co.reqtype)
lib.dbg('routing with negotiated type of ', {mtt.ptr,mtt.ct})
route.dispatch_http(&co, uri)
::fail::
if co.uploads.run > 0 then
for i=0,co.uploads.sz do
co.uploads(i).filename:free()
co.uploads(i).field:free()
................................................................................
--
-- return 0
--end
terra cfgcache.methods.load :: {&cfgcache} -> {}
terra cfgcache:init(o: &srv)
self.overlord = o
self:load()
end
terra srv:setup(befile: rawstring)
cfg(self, befile)
var success = false
if self.sources.ct == 0 then lib.bail('no data sources specified') end
................................................................................
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
if iname ~= nil then
................................................................................
bind = dbbind.ptr
else bind = '[::1]:10917' end
lib.report('binding to ', bind)
lib.net.mg_mgr_init(&self.webmgr)
self.webcon = lib.net.mg_http_listen(&self.webmgr, bind, handle.http, self)
if dbbind.ptr ~= nil then dbbind:free() end
end
terra srv:poll()
lib.net.mg_mgr_poll(&self.webmgr,300)
end
terra srv:shutdown()
................................................................................
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 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
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')
if sreg:ref() 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.pol_sec = secmode.private
elseif lib.str.cmp(smode.ptr, 'lockdown') == 0 then
self.pol_sec = secmode.lockdown
elseif lib.str.cmp(smode.ptr, 'isolate') == 0 then
self.pol_sec = secmode.isolate
end
smode:free()
end
self.ui_hue = self:cfint('ui-accent',config.default_ui_accent)
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')
self.ui_cue_founder = self.overlord:conf_get('ui-profile-cue-master')
self.usrdef_pol_follow = self.overlord:conf_get('user-default-acl-follow')
self.usrdef_pol_follow_req = self.overlord:conf_get('user-default-acl-follow-req')
end
return {
overlord = srv;
convo = convo;
route = route;
secmode = secmode;
}
|
> | | > > | | < < < < | < < < > | | | | > > > > > > | < | > | > | < | > | > | < > | | | > | | > | | | > | > | | | | | | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 .. 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 ... 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 ... 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 ... 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 ... 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 ... 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 ... 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 |
-- vim: ft=terra
local util = lib.util
local secmode = lib.enum { 'public', 'private', 'lockdown', 'isolate' }
local pstring = lib.mem.ptr(int8)
local struct srv
local struct cfgcache {
_pool: lib.mem.pool
secret: pstring
pol_sec: secmode.t
pol_reg: bool
pol_autoherald: bool
credmgd: bool
maxupsz: intptr
poolinitsz: intptr
................................................................................
webmgr: lib.net.mg_mgr
webcon: &lib.net.mg_connection
cfg: cfgcache
id: rawstring
pool: lib.mem.pool
}
terra cfgcache:purge()
self._pool:clear()
end
terra cfgcache:free()
self._pool:free()
end
terra srv:post_enum_author_uid(uid: uint64, r: lib.store.range): lib.mem.vec(lib.mem.ptr(lib.store.post))
var all: lib.mem.vec(lib.mem.ptr(lib.store.post)) all:init(64)
for i=0,self.sources.ct do var src = self.sources.ptr + i
if src.handle ~= nil and src.backend.timeline_instance_fetch ~= nil then
var lst = src:post_enum_author_uid(uid,r)
................................................................................
co:complain(400,'bad request','unrecognized content-type')
goto fail
end
var boundary = pstring {ptr=p+9,ct=ctt.ct - ((p - ctt.ptr) + 9)}
co.method = lib.http.method.post_file
co.uploads:init(8)
var bsr = co:qstr('\r\n--',boundary,'\r\n')
var upmap = lib.str.splitmap(co.body,bsr,8)
-- first entry may not be preceded by header-break
if lib.str.find(upmap(0), pstring {
ptr = bsr.ptr + 2, ct = bsr.ct - 2
}):ref() then
upmap(0).ptr = upmap(0).ptr + (bsr.ct - 2)
................................................................................
nextup.field = fld
nextup.filename = file
end
end
end
end
end
upmap:free()
end
end
end
route.dispatch_http(&co, uri)
::fail::
if co.uploads.run > 0 then
for i=0,co.uploads.sz do
co.uploads(i).filename:free()
co.uploads(i).field:free()
................................................................................
--
-- return 0
--end
terra cfgcache.methods.load :: {&cfgcache} -> {}
terra cfgcache:init(o: &srv)
self.overlord = o
self._pool:init(256)
self:load()
end
terra srv:setup(befile: rawstring)
cfg(self, befile)
var success = false
if self.sources.ct == 0 then lib.bail('no data sources specified') end
................................................................................
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(&self.pool, '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
if iname ~= nil then
................................................................................
bind = dbbind.ptr
else bind = '[::1]:10917' end
lib.report('binding to ', bind)
lib.net.mg_mgr_init(&self.webmgr)
self.webcon = lib.net.mg_http_listen(&self.webmgr, bind, handle.http, self)
--if dbbind.ptr ~= nil then dbbind:free() end
end
terra srv:poll()
lib.net.mg_mgr_poll(&self.webmgr,300)
end
terra srv:shutdown()
................................................................................
lib.report('closing data source ', src.id.ptr, '(', src.backend.id, ')')
src:close()
end
self.sources:free()
self.pool:free()
end
terra cfgcache:cfstr(name: pstring)
return self.overlord:conf_get(&self._pool, name)
end
terra cfgcache:cfint(name: pstring, default: intptr)
var f = self._pool:frame()
var str = self:cfstr(name)
defer self._pool:reset(f)
if str.ptr ~= nil then
var i,ok = lib.math.decparse(str)
if ok then default = i else
lib.warn('invalid configuration setting ',{name.ptr,name.ct},'="',{str.ptr,str.ct},'", expected integer; using default value instead')
end
end
return default
end
terra cfgcache:cffsz(name: pstring, default: intptr)
var f = self._pool:frame()
var str = self:cfstr(name)
defer self._pool:reset(f)
if str:ref() then
var sz, ok = lib.math.fsz_parse(str)
if ok then default = sz else
lib.warn('invalid configuration setting ',{name.ptr,name.ct},'="',{str.ptr,str.ct},'", expected byte length; using default value instead')
end
end
return default
end
terra cfgcache:cfbool(name: pstring, default: bool)
var f = self._pool:frame()
var str = self:cfstr(name)
defer self._pool:reset(f)
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.ptr,name.ct},'="',{str.ptr,str.ct},'", expected boolean; using default value instead')
end
end
return default
end
terra cfgcache:load()
self.instance = self:cfstr('instance-name')
self.domain = self:cfstr('domain')
self.secret = self:cfstr('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 fr = self._pool:frame()
var sreg = self:cfstr('credential-store')
if sreg:ref() then
if lib.str.cmp(sreg.ptr, 'managed') == 0
then self.credmgd = true
else self.credmgd = false
end
self._pool:reset(fr)
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
do var fr = self._pool:frame()
var smode = self:cfstr('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.pol_sec = secmode.private
elseif lib.str.cmp(smode.ptr, 'lockdown') == 0 then
self.pol_sec = secmode.lockdown
elseif lib.str.cmp(smode.ptr, 'isolate') == 0 then
self.pol_sec = secmode.isolate
end
self._pool:reset(fr)
end end
self.ui_hue = self:cfint('ui-accent',config.default_ui_accent)
self.nranks = self:cfint('user-ranks',10)
self.maxinvites = self:cfint('max-invites',64)
do var fr = self._pool:frame()
var webmaster = self:cfstr('master')
defer self._pool:reset(fr)
if webmaster:ref() then
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 end
self.ui_cue_staff = self:cfstr('ui-profile-cue-staff')
self.ui_cue_founder = self:cfstr('ui-profile-cue-master')
self.usrdef_pol_follow = self:cfstr('user-default-acl-follow')
self.usrdef_pol_follow_req = self:cfstr('user-default-acl-follow-req')
end
return {
overlord = srv;
convo = convo;
route = route;
secmode = secmode;
}
|
Modified store.t from [6e43eba049] to [54bd5bc381].
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
-- these two functions are special, in that they should be called
-- directly on a specific backend, rather than passed down to the
-- backends by the server; that is pathological behavior that will
-- not have the desired effect
server_setup_self: {&m.source, rawstring, lib.mem.ptr(uint8)} -> {}
conf_get: {&m.source, lib.str.t} -> lib.mem.ptr(int8)
conf_set: {&m.source, lib.str.t, lib.str.t} -> {}
conf_reset: {&m.source, rawstring} -> {}
actor_create: {&m.source, &m.actor} -> uint64
actor_save: {&m.source, &m.actor} -> {}
actor_save_privs: {&m.source, &m.actor} -> {}
actor_purge_uid: {&m.source, uint64} -> {}
|
| |
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
-- these two functions are special, in that they should be called
-- directly on a specific backend, rather than passed down to the
-- backends by the server; that is pathological behavior that will
-- not have the desired effect
server_setup_self: {&m.source, rawstring, lib.mem.ptr(uint8)} -> {}
conf_get: {&m.source, &lib.mem.pool, lib.str.t} -> lib.mem.ptr(int8)
conf_set: {&m.source, lib.str.t, lib.str.t} -> {}
conf_reset: {&m.source, rawstring} -> {}
actor_create: {&m.source, &m.actor} -> uint64
actor_save: {&m.source, &m.actor} -> {}
actor_save_privs: {&m.source, &m.actor} -> {}
actor_purge_uid: {&m.source, uint64} -> {}
|