From 24980124530bb8fb680c1a23ba1c1847556d5986 Mon Sep 17 00:00:00 2001 From: vangheem Date: Tue, 20 Mar 2018 08:24:31 -0400 Subject: [PATCH] Fix TUS upload with zero length files --- CHANGELOG.rst | 3 +- guillotina/files/manager.py | 2 +- guillotina/tests/test_attachment.py | 62 +++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7958ea5d6..5269c0fd7 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,7 +1,8 @@ 2.5.5 (unreleased) ------------------ -- Nothing changed yet. +- Fix TUS upload with zero length files + [vangheem] 2.5.4 (2018-03-19) diff --git a/guillotina/files/manager.py b/guillotina/files/manager.py index c26d0ffa2..15d77bc70 100644 --- a/guillotina/files/manager.py +++ b/guillotina/files/manager.py @@ -133,7 +133,7 @@ async def tus_patch(self, *args, **kwargs): 'Tus-Upload-Finished']) } - if self.dm.get('size') and self.dm.get_offset() >= self.dm.get('size'): + if self.dm.get('size') is not None and self.dm.get_offset() >= self.dm.get('size'): await self.file_storage_manager.finish(self.dm) await self.dm.finish() headers['Tus-Upload-Finished'] = '1' diff --git a/guillotina/tests/test_attachment.py b/guillotina/tests/test_attachment.py index a03ba5aed..7634e3768 100644 --- a/guillotina/tests/test_attachment.py +++ b/guillotina/tests/test_attachment.py @@ -310,3 +310,65 @@ async def test_tus_unfinished_error(container_requester): ) # override it assert status == 201 + + +async def test_tus_with_empty_file(container_requester): + async with container_requester as requester: + response, status = await requester( + 'POST', + '/db/guillotina/', + data=json.dumps({ + '@type': 'Item', + '@behaviors': ['guillotina.behaviors.attachment.IAttachment'], + 'id': 'foobar' + }) + ) + assert status == 201 + + response, status = await requester( + 'OPTIONS', + '/db/guillotina/foobar/@tusupload/file') + assert status == 200 + + response, status = await requester( + 'POST', + '/db/guillotina/foobar/@tusupload/file', + headers={ + 'UPLOAD-LENGTH': '0', + 'TUS-RESUMABLE': '1.0.0' + } + ) + assert status == 201 + + response, status = await requester( + 'HEAD', + '/db/guillotina/foobar/@tusupload/file') + assert status == 200 + + response, status = await requester( + 'PATCH', + '/db/guillotina/foobar/@tusupload/file', + headers={ + 'CONTENT-LENGTH': '0', + 'TUS-RESUMABLE': '1.0.0', + 'upload-offset': '0' + }, + data=b'' + ) + assert status == 200 + + response, status = await requester( + 'GET', + '/db/guillotina/foobar/@download/file' + ) + assert status == 200 + assert len(response) == 0 + + request = utils.get_mocked_request(requester.db) + root = await utils.get_root(request) + async with managed_transaction(request=request, abort_when_done=True): + container = await root.async_get('guillotina') + obj = await container.async_get('foobar') + behavior = IAttachment(obj) + await behavior.load() + assert behavior.file._blob.chunks == 0