[Calypso] [PATCH] Return propfind-finite-depth on infinite depth requests

Guido Günther agx at sigxcpu.org
Sat Apr 9 16:42:52 PDT 2016


as suggested by

    http://www.webdav.org/specs/rfc4918.html#rfc.section.9.1.1

This fixes large parts caldav-testers tests/CalDAV/propfind.xml and
I would be keen to find out if it breaks real world clients.
---
 calypso/__init__.py | 16 +++++++++++-----
 calypso/xmlutils.py | 14 ++++++++++++--
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/calypso/__init__.py b/calypso/__init__.py
index 40987dd..b07fcbe 100644
--- a/calypso/__init__.py
+++ b/calypso/__init__.py
@@ -395,13 +395,19 @@ class CollectionHTTPHandler(server.BaseHTTPRequestHandler):
         try:
             xml_request = self.xml_request
             log.debug("PROPFIND %s", xml_request)
-            self._answer = xmlutils.propfind(
-                self.path, xml_request, self._collection,
-                self.headers.get("depth", "infinity"),
-                context)
+            depth = self.headers.get("depth", "infinity")
+            if depth != "infinity":
+                self._answer = xmlutils.propfind(
+                    self.path, xml_request, self._collection,
+                    depth, context)
+                status = client.MULTI_STATUS
+            else:
+                self._answer = xmlutils.propfind_deny()
+                status = client.FORBIDDEN
+
             log.debug("PROPFIND ANSWER %s", self._answer)
 
-            self.send_calypso_response(client.MULTI_STATUS, len(self._answer))
+            self.send_calypso_response(status, len(self._answer))
             self.send_header("DAV", "1, calendar-access")
             self.send_header("Content-Type", "text/xml")
             self.end_headers()
diff --git a/calypso/xmlutils.py b/calypso/xmlutils.py
index af2ad86..a1c5ba7 100644
--- a/calypso/xmlutils.py
+++ b/calypso/xmlutils.py
@@ -133,8 +133,7 @@ def propfind(path, xml_request, collection, depth, context):
             if depth == "0":
                 items = [collection]
             else:
-                # depth is 1, infinity or not specified
-                # we limit ourselves to depth == 1
+                # We limit ourselves to depth == 1
                 items = [collection] + collection.items
     else:
         items = []
@@ -228,6 +227,17 @@ def propfind(path, xml_request, collection, depth, context):
     return ET.tostring(multistatus, config.get("encoding", "request"))
 
 
+def propfind_deny():
+    """Answer an infinity PROPFIND requests.
+
+    Read rfc4918-9.1.1 for info.
+    """
+    error = ET.Element(_tag("D", "error"))
+    prec_code = ET.Element(_tag("D", "propfind-finite-depth"))
+    error.append(prec_code)
+    return ET.tostring(error, config.get("encoding", "request"))
+
+
 def put(path, webdav_request, collection, context):
     """Read PUT requests."""
     name = paths.resource_from_path(path)
-- 
2.8.0.rc3


More information about the Calypso mailing list