From c8d5f335b1d0d4c461a6bf214da01b5041f58532 Mon Sep 17 00:00:00 2001 From: Leo Vasanko Date: Mon, 13 Nov 2023 02:00:44 -0800 Subject: [PATCH] Fix upload of zero-sized files. --- cista/api.py | 13 ++++++++++--- cista/fileio.py | 6 ++++-- frontend/src/components/UploadButton.vue | 5 +---- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/cista/api.py b/cista/api.py index c97d893..99da767 100644 --- a/cista/api.py +++ b/cista/api.py @@ -37,16 +37,23 @@ async def upload(req, ws): ) req = msgspec.json.decode(text, type=FileRange) pos = req.start - data = None - while pos < req.end and (data := await ws.recv()) and isinstance(data, bytes): + while True: + data = await ws.recv() + if not isinstance(data, bytes): + break + if len(data) > req.end - pos: + raise ValueError( + f"Expected up to {req.end - pos} bytes, got {len(data)} bytes" + ) sentsize = await alink(("upload", req.name, pos, data, req.size)) pos += typing.cast(int, sentsize) + if pos >= req.end: + break if pos != req.end: d = f"{len(data)} bytes" if isinstance(data, bytes) else data raise ValueError(f"Expected {req.end - pos} more bytes, got {d}") # Report success res = StatusMsg(status="ack", req=req) - print("ack", res) await asend(ws, res) diff --git a/cista/fileio.py b/cista/fileio.py index 8a821d2..b9052f8 100644 --- a/cista/fileio.py +++ b/cista/fileio.py @@ -34,9 +34,11 @@ class File: self.open_rw() assert self.fd is not None if file_size is not None: + assert pos + len(buffer) <= file_size os.ftruncate(self.fd, file_size) - os.lseek(self.fd, pos, os.SEEK_SET) - os.write(self.fd, buffer) + if buffer: + os.lseek(self.fd, pos, os.SEEK_SET) + os.write(self.fd, buffer) def __getitem__(self, slice): if self.fd is None: diff --git a/frontend/src/components/UploadButton.vue b/frontend/src/components/UploadButton.vue index 32d7ea0..39dd239 100644 --- a/frontend/src/components/UploadButton.vue +++ b/frontend/src/components/UploadButton.vue @@ -166,10 +166,6 @@ const worker = async () => { const ws = await WSCreate() while (upqueue.length) { const f = upqueue[0] - if (f.cloudPos === f.file.size) { - upqueue.shift() - continue - } const start = f.cloudPos const end = Math.min(f.file.size, start + (1<<20)) const control = { name: f.cloudName, size: f.file.size, start, end } @@ -180,6 +176,7 @@ const worker = async () => { ws.sendMsg(control) // @ts-ignore await ws.sendData(data) + if (f.cloudPos === f.file.size) upqueue.shift() } if (upqueue.length) startWorker() uprogress.status = "idle"