Skip to content

Commit 25488b1

Browse files
Log authentication warnings for servers behind proxies and/or returning HTML on 401.
Improved DAVClient docstring to encourage auth parameter usage when no server auth probing is wanted/needed.
1 parent 20a757e commit 25488b1

1 file changed

Lines changed: 26 additions & 3 deletions

File tree

caldav/davclient.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,15 +462,22 @@ def __init__(
462462
Parameters:
463463
* url: A fully qualified url: `scheme://user:pass@hostname:port`
464464
* proxy: A string defining a proxy server: `hostname:port`
465+
* auth: A niquests.auth.AuthBase or requests.auth.AuthBase object.
466+
Use when the server's auth scheme is known.
467+
Otherwise, pass username and password instead.
465468
* username and password should be passed as arguments or in the URL
466469
* auth, timeout and ssl_verify_cert are passed to niquests.request.
467470
* ssl_verify_cert can be the path of a CA-bundle or False.
468471
* huge_tree: boolean, enable XMLParser huge_tree to handle big events, beware
469472
of security issues, see : https://lxml.de/api/lxml.etree.XMLParser-class.html
470473
471-
The niquests library will honor a .netrc-file, if such a file exists
472-
username and password may be omitted. Known bug: .netrc is honored
473-
even if a username/password is given, ref https://github.com/python-caldav/caldav/issues/206
474+
The requests library will honor a .netrc-file, if such a file exists
475+
username and password may be omitted. Known bugs:
476+
- .netrc is honored even if a username/password is given,
477+
ref https://github.com/python-caldav/caldav/issues/206
478+
- If the caldav server is behind a proxy or replies with html instead of xml
479+
when returning 401, warnings will be printed which might be unwanted.
480+
Check auth parameter for details.
474481
"""
475482
headers = headers or {}
476483

@@ -826,6 +833,22 @@ def request(
826833
cert=self.ssl_cert,
827834
)
828835
log.debug("server responded with %i %s" % (r.status_code, r.reason))
836+
if r.status_code == 401 and 'text/html' in self.headers.get("Content-Type", "") and not self.auth:
837+
# The server can return HTML on 401 sometimes (ie. it's behind a proxy)
838+
# The user can avoid logging errors by setting the authentication type by themselves.
839+
msg = (
840+
"No authentication object was provided. "
841+
"HTML was returned when probing the server for supported authentication types. "
842+
"To avoid logging errors, consider setting the authentication type manually via DAVClient(auth=...)"
843+
)
844+
if r.headers.get("WWW-Authenticate"):
845+
auth_types = [
846+
t for t in self.extract_auth_types(r.headers["WWW-Authenticate"])
847+
if t in ["basic", "digest", "bearer"]
848+
]
849+
if auth_types:
850+
msg += "\nSupported authentication types: %s" % (", ".join(auth_types))
851+
log.warning(msg)
829852
response = DAVResponse(r, self)
830853
except:
831854
## this is a workaround needed due to some weird server

0 commit comments

Comments
 (0)