Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 45 additions & 49 deletions caldav/davclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,64 +73,60 @@ def __init__(
if davclient:
self.huge_tree = davclient.huge_tree

## TODO: this if/else/elif could possibly be refactored, or we should
## consider to do streaming into the xmltree library as originally
## intended. It only makes sense for really huge payloads though.
if self.headers.get("Content-Type", "").startswith(
"text/xml"
) or self.headers.get("Content-Type", "").startswith("application/xml"):
try:
content_length = int(self.headers["Content-Length"])
except:
content_length = -1
if content_length == 0 or not self._raw:
self._raw = ""
self.tree = None
log.debug("No content delivered")
else:
## With response.raw we could be streaming the content, but it does not work because
## the stream often is compressed. We could add uncompression on the fly, but not
## considered worth the effort as for now.
# self.tree = etree.parse(response.raw, parser=etree.XMLParser(remove_blank_text=True))
try:
self.tree = etree.XML(
self._raw,
parser=etree.XMLParser(
remove_blank_text=True, huge_tree=self.huge_tree
),
)
except:
logging.critical(
"Expected some valid XML from the server, but got this: \n"
+ str(self._raw),
exc_info=True,
)
raise
if log.level <= logging.DEBUG:
log.debug(etree.tostring(self.tree, pretty_print=True))
elif self.headers.get("Content-Type", "").startswith(
"text/calendar"
) or self.headers.get("Content-Type", "").startswith("text/plain"):
## text/plain is typically for errors, we shouldn't see it on 200/207 responses.
## TODO: may want to log an error if it's text/plain and 200/207.
## Logic here was moved when refactoring
pass
content_type = self.headers.get("Content-Type", "")
xml = ["text/xml", "application/xml"]
no_xml = ["text/plain", "text/calendar"]
expect_xml = any((content_type.startswith(x) for x in xml))
expect_no_xml = any((content_type.startswith(x) for x in no_xml))
try:
content_length = int(self.headers["Content-Length"])
except:
content_length = -1
if content_length == 0 or not self._raw:
self._raw = ""
self.tree = None
log.debug("No content delivered")
else:
## Probably no content type given (iCloud). Some servers
## give text/html as the default when no content is
## delivered or on errors (ref
## https://github.com/python-caldav/caldav/issues/142).
## TODO: maybe just remove all of the code above in this if/else and let all
## data be parsed through this code.
## For really huge objects we should pass the object as a stream to the
## XML parser, like this:
# self.tree = etree.parse(response.raw, parser=etree.XMLParser(remove_blank_text=True))
## However, we would also need to decompress on the fly. I won't bother now.
try:
## https://github.com/python-caldav/caldav/issues/142
## We cannot trust the content=type (iCloud, OX and others).
## We'll try to parse the content as XML no matter
## the content type given.
self.tree = etree.XML(
self._raw,
parser=etree.XMLParser(
remove_blank_text=True, huge_tree=self.huge_tree
),
)
except:
pass
## Content wasn't XML. What does the content-type say?
## expect_no_xml means text/plain or text/calendar
## expect_no_xml -> ok, pass on, with debug logging
## expect_xml means text/xml or application/xml
## expect_xml -> raise an error
## anything else (text/plain, text/html, ''),
## log an error and continue
if not expect_no_xml or log.level <= logging.DEBUG:
if not expect_no_xml:
_log = logging.critical
else:
_log = logging.debug
## The statement below may not be true.
## We may be expecting something else
_log(
"Expected some valid XML from the server, but got this: \n"
+ str(self._raw),
exc_info=True,
)
if expect_xml:
raise
else:
if log.level <= logging.DEBUG:
log.debug(etree.tostring(self.tree, pretty_print=True))

## this if will always be true as for now, see other comments on streaming.
if hasattr(self, "_raw"):
Expand Down