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