diff --git a/radicale/__init__.py b/radicale/__init__.py index fb23675..51bb34c 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -533,7 +533,9 @@ class Application: content_type = environ.get("CONTENT_TYPE") if content_type: tags = {value: key for key, value in storage.MIMETYPES.items()} - collection.set_meta("tag", tags[content_type.split(";")[0]]) + tag = tags.get(content_type.split(";")[0]) + if tag: + collection.set_meta("tag", tag) headers = {} item_name = xmlutils.name_from_path(environ["PATH_INFO"], collection) item = collection.get(item_name) @@ -546,21 +548,26 @@ class Application: # Case 1: No item and no ETag precondition: Add new item # Case 2: Item and ETag precondition verified: Modify item # Case 3: Item and no Etag precondition: Force modifying item - items = list(vobject.readComponents(content)) - if items: - if item: - # PUT is modifying an existing item + items = list(vobject.readComponents(content or "")) + if item: + # PUT is modifying an existing item + if items: new_item = collection.update(item_name, items[0]) - elif item_name: - # PUT is adding a new item + else: + new_item = None + elif item_name: + # PUT is adding a new item + if items: new_item = collection.upload(item_name, items[0]) else: - # PUT is replacing the whole collection - collection.delete() - new_item = self.Collection.create_collection( - environ["PATH_INFO"], items) - if new_item: - headers["ETag"] = new_item.etag + new_item = None + else: + # PUT is replacing the whole collection + collection.delete() + new_item = self.Collection.create_collection( + environ["PATH_INFO"], items) + if new_item: + headers["ETag"] = new_item.etag status = client.CREATED else: # PUT rejected in all other cases diff --git a/radicale/storage.py b/radicale/storage.py index b135f20..b63a3e5 100644 --- a/radicale/storage.py +++ b/radicale/storage.py @@ -578,23 +578,26 @@ class Collection(BaseCollection): except OSError: cls.logger.debug("Locking not supported") cls._lock_file_locked = True - yield - with cls._lock: - if mode == "r": - cls._readers -= 1 - else: - cls._writer = False - if cls._readers == 0: - if os.name == "nt": - handle = msvcrt.get_osfhandle(cls._lock_file.fileno()) - overlapped = Overlapped() - if not unlock_file_ex(handle, 0, 1, 0, overlapped): - cls.logger.debug("Unlocking not supported") - elif os.name == "posix": - try: - fcntl.lockf(cls._lock_file.fileno(), fcntl.LOCK_UN) - except OSError: - cls.logger.debug("Unlocking not supported") - cls._lock_file_locked = False - if cls._waiters: - cls._waiters[0].notify() + try: + yield + finally: + with cls._lock: + if mode == "r": + cls._readers -= 1 + else: + cls._writer = False + if cls._readers == 0: + if os.name == "nt": + handle = msvcrt.get_osfhandle(cls._lock_file.fileno()) + overlapped = Overlapped() + if not unlock_file_ex(handle, 0, 1, 0, overlapped): + cls.logger.debug("Unlocking not supported") + elif os.name == "posix": + try: + fcntl.lockf(cls._lock_file.fileno(), + fcntl.LOCK_UN) + except OSError: + cls.logger.debug("Unlocking not supported") + cls._lock_file_locked = False + if cls._waiters: + cls._waiters[0].notify()