If I do REPORT requests, the following line would raise a KeyError:

    items = [collection.items[name]]

Wrapping it with a try-except block obviously fixes that issue.

At least for REPORT requests, Radicale now also returns proper HTTP
status codes when items or just its properties couldn't be found.
This commit is contained in:
Markus Unterwaditzer 2015-02-08 17:52:55 +01:00
parent a7700f9805
commit 1126f318af

View File

@ -504,46 +504,84 @@ def report(path, xml_request, collection):
if name:
# Reference is an item
path = "/".join(hreference.split("/")[:-1]) + "/"
try:
items = [collection.items[name]]
except KeyError:
multistatus.append(_item_response(hreference,
found_item=False))
continue
else:
# Reference is a collection
path = hreference
items = collection.components
for item in items:
href = _href("%s/%s" % (path.rstrip("/"), item.name))
if tag_filters and item.tag not in tag_filters:
continue
response = ET.Element(_tag("D", "response"))
multistatus.append(response)
href = ET.Element(_tag("D", "href"))
href.text = _href("%s/%s" % (path.rstrip("/"), item.name))
response.append(href)
propstat = ET.Element(_tag("D", "propstat"))
response.append(propstat)
prop = ET.Element(_tag("D", "prop"))
propstat.append(prop)
found_props = []
not_found_props = []
for tag in props:
element = ET.Element(tag)
if tag == _tag("D", "getetag"):
element.text = item.etag
found_props.append(element)
elif tag == _tag("D", "getcontenttype"):
element.text = "%s; component=%s" % (
item.mimetype, item.tag.lower())
found_props.append(element)
elif tag in (_tag("C", "calendar-data"),
_tag("CR", "address-data")):
if isinstance(item, ical.Component):
element.text = ical.serialize(
collection_tag, collection_headers,
collection_timezones + [item])
prop.append(element)
found_props.append(element)
else:
not_found_props.append(element)
status = ET.Element(_tag("D", "status"))
status.text = _response(200)
propstat.append(status)
multistatus.append(_item_response(href, found_props=found_props,
not_found_props=not_found_props,
found_item=True))
return _pretty_xml(multistatus)
def _item_response(href, found_props=(), not_found_props=(), found_item=True):
response = ET.Element(_tag("D", "response"))
href_tag = ET.Element(_tag("D", "href"))
href_tag.text = href
response.append(href_tag)
if found_item:
if found_props:
propstat = ET.Element(_tag("D", "propstat"))
status = ET.Element(_tag("D", "status"))
status.text = _response(200)
prop = ET.Element(_tag("D", "prop"))
for p in found_props:
prop.append(p)
propstat.append(prop)
propstat.append(status)
response.append(propstat)
if not_found_props:
propstat = ET.Element(_tag("D", "propstat"))
status = ET.Element(_tag("D", "status"))
status.text = _response(404)
prop = ET.Element(_Tag("D", "prop"))
for p in not_found_props:
prop.append(p)
propstat.append(prop)
propstat.append(status)
response.append(propstat)
else:
status = ET.Element(_tag("D", "status"))
status.text = _response(404)
response.append(status)
return response