From c1da6872dd57a02e5ac3ed2ea4520afc559f49e5 Mon Sep 17 00:00:00 2001 From: Guillaume Ayoub Date: Thu, 28 Apr 2011 18:04:34 +0200 Subject: [PATCH] Add support for PROPPATCH requests --- radicale/__init__.py | 14 +++++++++++++- radicale/xmlutils.py | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/radicale/__init__.py b/radicale/__init__.py index ef11e52..ad1a4db 100644 --- a/radicale/__init__.py +++ b/radicale/__init__.py @@ -291,7 +291,7 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler): self.send_response(client.OK) self.send_header( "Allow", "DELETE, HEAD, GET, MKCALENDAR, " - "OPTIONS, PROPFIND, PUT, REPORT") + "OPTIONS, PROPFIND, PROPPATCH, PUT, REPORT") self.send_header("DAV", "1, calendar-access") self.end_headers() @@ -309,6 +309,18 @@ class CalendarHTTPHandler(server.BaseHTTPRequestHandler): self.end_headers() self.wfile.write(self._answer) + @log_request_content + def do_PROPPATCH(self): + """Manage PROPPATCH request.""" + self._answer = xmlutils.proppatch() + + self.send_response(client.MULTI_STATUS) + self.send_header("DAV", "1, calendar-access") + self.send_header("Content-Length", len(self._answer)) + self.send_header("Content-Type", "text/xml") + self.end_headers() + self.wfile.write(self._answer) + @log_request_content @check_rights def do_PUT(self): diff --git a/radicale/xmlutils.py b/radicale/xmlutils.py index 1196883..7e8a399 100644 --- a/radicale/xmlutils.py +++ b/radicale/xmlutils.py @@ -179,6 +179,46 @@ def propfind(path, xml_request, calendar, depth): return ET.tostring(multistatus, config.get("encoding", "request")) +def proppatch(path, xml_request, calendar): + """Read and answer PROPPATCH requests. + + Read rfc4918-9.2 for info. + + """ + # Reading request + root = ET.fromstring(xml_request) + + prop_element = root.find(_tag("D", "prop")) + prop_list = prop_element.getchildren() + props = [prop.tag for prop in prop_list] + + # Writing answer + multistatus = ET.Element(_tag("D", "multistatus")) + + response = ET.Element(_tag("D", "response")) + multistatus.append(response) + + href = ET.Element(_tag("D", "href")) + href.text = path + response.append(href) + + propstat = ET.Element(_tag("D", "propstat")) + response.append(propstat) + + prop = ET.Element(_tag("D", "prop")) + propstat.append(prop) + + for tag in props: + element = ET.Element(tag) + prop.append(element) + + status = ET.Element(_tag("D", "status")) + status.text = _response(200) + propstat.append(status) + + return ET.tostring(multistatus, config.get("encoding", "request")) + + def put(path, ical_request, calendar): """Read PUT requests.""" name = name_from_path(path, calendar)