From 217859bf5e4e8803274a28e00d6c89618cbb51a9 Mon Sep 17 00:00:00 2001 From: Unrud Date: Wed, 7 Jun 2017 14:13:12 +0200 Subject: [PATCH 1/4] Fix empty REPORT requests --- radicale/xmlutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index 248cd8f6..b48dfbda 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -997,7 +997,7 @@ def report(base_prefix, path, xml_request, collection): """ multistatus = ET.Element(_tag("D", "multistatus")) if xml_request is None: - return multistatus + return client.MULTI_STATUS, multistatus root = xml_request if root.tag in ( _tag("D", "principal-search-property-set"), From 1b54b23bb314eea24377a8946789564e97e82540 Mon Sep 17 00:00:00 2001 From: Unrud Date: Wed, 7 Jun 2017 14:14:09 +0200 Subject: [PATCH 2/4] Add info about disabling locking to error message --- radicale/storage.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/radicale/storage.py b/radicale/storage.py index 711e7fc3..f77143ce 100644 --- a/radicale/storage.py +++ b/radicale/storage.py @@ -1268,17 +1268,20 @@ class Collection(BaseCollection): flags = LOCKFILE_EXCLUSIVE_LOCK if mode == "w" else 0 overlapped = Overlapped() if not lock_file_ex(handle, flags, 0, 1, 0, overlapped): - raise RuntimeError("Locking the storage failed: %s" % - ctypes.FormatError()) + raise RuntimeError("Locking the storage failed " + "(can be disabled in the config): " + "%s" % ctypes.FormatError()) elif os.name == "posix": _cmd = fcntl.LOCK_EX if mode == "w" else fcntl.LOCK_SH try: fcntl.flock(cls._lock_file.fileno(), _cmd) except OSError as e: - raise RuntimeError("Locking the storage failed: %s" % - e) from e + raise RuntimeError("Locking the storage failed " + "(can be disabled in the config): " + "%s" % e) from e else: - raise RuntimeError("Locking the storage failed: " + raise RuntimeError("Locking the storage failed " + "(can be disabled in the config): " "Unsupported operating system") cls._lock_file_locked = True try: From 13381fb829e3928cead852d20f6e1482ffc1acf6 Mon Sep 17 00:00:00 2001 From: Unrud Date: Wed, 7 Jun 2017 14:15:30 +0200 Subject: [PATCH 3/4] Change logging level of invalid sync token to warning Some clients stop to work, when told their sync-token are invalid. --- radicale/xmlutils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index b48dfbda..68603b95 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -1039,8 +1039,8 @@ def report(base_prefix, path, xml_request, collection): sync_token, names = collection.sync(old_sync_token) except ValueError as e: # Invalid sync token - collection.logger.info("Client provided invalid sync token %r: %s", - old_sync_token, e, exc_info=True) + collection.logger.warning("Client provided invalid sync token %r: " + "%s", old_sync_token, e, exc_info=True) return client.PRECONDITION_FAILED, None hreferences = ("/" + posixpath.join(collection.path, n) for n in names) # Append current sync token to response From 3753364fc801f83b0ac9c6afa579613523d18c09 Mon Sep 17 00:00:00 2001 From: Unrud Date: Wed, 7 Jun 2017 14:16:18 +0200 Subject: [PATCH 4/4] XML error message for invalid sync-token --- radicale/__init__.py | 2 -- radicale/xmlutils.py | 10 +++++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/radicale/__init__.py b/radicale/__init__.py index ae53c893..f70e58dc 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -842,6 +842,4 @@ class Application: headers = {"Content-Type": "text/xml; charset=%s" % self.encoding} status, xml_answer = xmlutils.report( base_prefix, path, xml_content, collection) - if status == client.PRECONDITION_FAILED: - return PRECONDITION_FAILED return (status, headers, self._write_xml_content(xml_answer)) diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index 68603b95..ff91f822 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -127,6 +127,13 @@ def _href(base_prefix, href): return quote("%s%s" % (base_prefix, href)) +def _webdav_error(namespace, name): + """Generate XML error message.""" + root = ET.Element(_tag("D", "error")) + root.append(ET.Element(_tag(namespace, name))) + return root + + def _date_to_datetime(date_): """Transform a date to a UTC datetime. @@ -1041,7 +1048,8 @@ def report(base_prefix, path, xml_request, collection): # Invalid sync token collection.logger.warning("Client provided invalid sync token %r: " "%s", old_sync_token, e, exc_info=True) - return client.PRECONDITION_FAILED, None + return (client.PRECONDITION_FAILED, + _webdav_error("D", "valid-sync-token")) hreferences = ("/" + posixpath.join(collection.path, n) for n in names) # Append current sync token to response sync_token_element = ET.Element(_tag("D", "sync-token"))