Fully fix #258
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:
parent
a7700f9805
commit
1126f318af
@ -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]) + "/"
|
||||||
|
try:
|
||||||
items = [collection.items[name]]
|
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
|
||||||
|
Loading…
Reference in New Issue
Block a user