add ability to set lifetime per-file during upload

This commit is contained in:
ed 2022-09-18 13:12:38 +02:00
parent 13cc33e0a5
commit 09cea66aa8
3 changed files with 41 additions and 16 deletions

View file

@ -1190,6 +1190,9 @@ upload modifiers:
|--|--|--| |--|--|--|
| `Accept: url` | `want=url` | return just the file URL | | `Accept: url` | `want=url` | return just the file URL |
| `Rand: 4` | `rand=4` | generate random filename with 4 characters | | `Rand: 4` | `rand=4` | generate random filename with 4 characters |
| `Life: 30` | `life=30` | delete file after 30 seconds |
`life` only has an effect if the volume has a lifetime, and the volume lifetime must be greater than the file's
server behavior of `msg` can be reconfigured with `--urlform` server behavior of `msg` can be reconfigured with `--urlform`

View file

@ -720,6 +720,7 @@ class HttpCli(object):
# post_sz, sha_hex, sha_b64, remains, path, url # post_sz, sha_hex, sha_b64, remains, path, url
reader, remains = self.get_body_reader() reader, remains = self.get_body_reader()
vfs, rem = self.asrv.vfs.get(self.vpath, self.uname, False, True) vfs, rem = self.asrv.vfs.get(self.vpath, self.uname, False, True)
rnd, want_url, lifetime = self.upload_flags(vfs)
lim = vfs.get_dbv(rem)[0].lim lim = vfs.get_dbv(rem)[0].lim
fdir = vfs.canonical(rem) fdir = vfs.canonical(rem)
if lim: if lim:
@ -794,9 +795,8 @@ class HttpCli(object):
params.update(open_ka) params.update(open_ka)
srnd = self.uparam.get("rand", self.headers.get("rand", "")) if rnd and not self.args.nw:
if srnd and not self.args.nw: fn = self.rand_name(fdir, fn, rnd)
fn = self.rand_name(fdir, fn, int(srnd))
with ren_open(fn, *open_a, **params) as zfw: with ren_open(fn, *open_a, **params) as zfw:
f, fn = zfw["orz"] f, fn = zfw["orz"]
@ -823,7 +823,7 @@ class HttpCli(object):
rem, rem,
fn, fn,
self.ip, self.ip,
time.time(), time.time() - lifetime,
) )
vsuf = "" vsuf = ""
@ -863,7 +863,7 @@ class HttpCli(object):
self.reply(t.encode("utf-8")) self.reply(t.encode("utf-8"))
return True return True
def rand_name(self, fdir: str, fn: str, rnd: int): def rand_name(self, fdir: str, fn: str, rnd: int) -> str:
ok = False ok = False
try: try:
ext = "." + fn.rsplit(".", 1)[1] ext = "." + fn.rsplit(".", 1)[1]
@ -1281,6 +1281,22 @@ class HttpCli(object):
self.redirect(vpath, "?edit") self.redirect(vpath, "?edit")
return True return True
def upload_flags(self, vfs: VFS) -> tuple[int, bool, int]:
srnd = self.uparam.get("rand", self.headers.get("rand", ""))
rnd = int(srnd) if srnd and not self.args.nw else 0
ac = self.uparam.get(
"want", self.headers.get("accept", "").lower().split(";")[-1]
)
want_url = ac == "url"
zs = self.uparam.get("life", self.headers.get("life", ""))
if zs:
vlife = int(vfs.flags.get("lifetime") or 0)
lifetime = max(0, int(vlife - int(zs)))
else:
lifetime = 0
return rnd, want_url, lifetime
def handle_plain_upload(self) -> bool: def handle_plain_upload(self) -> bool:
assert self.parser assert self.parser
nullwrite = self.args.nw nullwrite = self.args.nw
@ -1296,12 +1312,7 @@ class HttpCli(object):
if not nullwrite: if not nullwrite:
bos.makedirs(fdir_base) bos.makedirs(fdir_base)
srnd = self.uparam.get("rand", self.headers.get("rand", "")) rnd, want_url, lifetime = self.upload_flags(vfs)
rnd = int(srnd) if srnd and not nullwrite else 0
ac = self.uparam.get(
"want", self.headers.get("accept", "").lower().split(";")[-1]
)
want_url = ac == "url"
files: list[tuple[int, str, str, str, str, str]] = [] files: list[tuple[int, str, str, str, str, str]] = []
# sz, sha_hex, sha_b64, p_file, fname, abspath # sz, sha_hex, sha_b64, p_file, fname, abspath
@ -1393,7 +1404,7 @@ class HttpCli(object):
vrem, vrem,
fname, fname,
self.ip, self.ip,
time.time(), time.time() - lifetime,
) )
self.conn.nbyte += sz self.conn.nbyte += sz

View file

@ -265,22 +265,29 @@ class Up2k(object):
def _sched_rescan(self) -> None: def _sched_rescan(self) -> None:
volage = {} volage = {}
cooldown = 0.0 cooldown = timeout = time.time() + 3.0
timeout = time.time() + 3
while True: while True:
now = time.time()
timeout = max(timeout, cooldown) timeout = max(timeout, cooldown)
wait = max(0.1, timeout + 0.1 - time.time()) wait = timeout - time.time()
# self.log("SR in {:.2f}".format(wait), 5)
with self.rescan_cond: with self.rescan_cond:
self.rescan_cond.wait(wait) self.rescan_cond.wait(wait)
now = time.time() now = time.time()
if now < cooldown: if now < cooldown:
# self.log("SR: cd - now = {:.2f}".format(cooldown - now), 5)
timeout = cooldown # wakeup means stuff to do, forget timeout
continue continue
if self.pp: if self.pp:
# self.log("SR: pp; cd := 1", 5)
cooldown = now + 1 cooldown = now + 1
continue continue
cooldown = now + 5
# self.log("SR", 5)
if self.args.no_lifetime: if self.args.no_lifetime:
timeout = now + 9001 timeout = now + 9001
else: else:
@ -302,7 +309,7 @@ class Up2k(object):
timeout = min(timeout, deadline) timeout = min(timeout, deadline)
if self.db_act > now - self.args.db_act: if self.db_act > now - self.args.db_act and self.need_rescan:
# recent db activity; defer volume rescan # recent db activity; defer volume rescan
act_timeout = self.db_act + self.args.db_act act_timeout = self.db_act + self.args.db_act
if self.need_rescan: if self.need_rescan:
@ -3073,6 +3080,10 @@ class Up2k(object):
with self.mutex: with self.mutex:
self.idx_wark(ptop, wark, rd, fn, inf.st_mtime, inf.st_size, ip, at) self.idx_wark(ptop, wark, rd, fn, inf.st_mtime, inf.st_size, ip, at)
if at and time.time() - at > 30:
with self.rescan_cond:
self.rescan_cond.notify_all()
def hash_file( def hash_file(
self, ptop: str, flags: dict[str, Any], rd: str, fn: str, ip: str, at: float self, ptop: str, flags: dict[str, Any], rd: str, fn: str, ip: str, at: float
) -> None: ) -> None: