diff options
author | Bjoern Kahl <mls@bjoern-kahl.de> | 2022-01-24 23:10:01 +0100 |
---|---|---|
committer | Tobias Brox <tobias@redpill-linpro.com> | 2022-01-26 22:15:21 +0100 |
commit | dd260173be7aba31d02891bb2d0e880893cd589e (patch) | |
tree | 58bcfd131c274835198f86f4461be56d0e7f8d1a | |
parent | bafa8103adee79ec4540b259be8672cbb9915584 (diff) | |
download | python-caldav-dd260173be7aba31d02891bb2d0e880893cd589e.zip |
Fix HTTP Auth failure with old (pre UTF-8) servers
Some servers, like really old SabreDAV based servers, seem to choke on
password if we pass a bytes sequence instead of a string to the
"requests" libraries HTTPDigestAuth object.
This Fix retries authentication in case of authentication failure with
the same password as plain string (which, in Python3 is anyway UTF-8).
Refreshed to address review comments.
-rw-r--r-- | caldav/davclient.py | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/caldav/davclient.py b/caldav/davclient.py index 14ac40d..98dadcb 100644 --- a/caldav/davclient.py +++ b/caldav/davclient.py @@ -545,6 +545,28 @@ class DAVClient: self.auth = requests.auth.HTTPDigestAuth(self.username, self.password) else: raise NotImplementedError("Auth method %s not supported yet" % auth_type) + return self.request(url, method, body, headers) + + elif (r.status_code == 401 and + 'WWW-Authenticate' in r.headers and + self.password and + self.username and + self.auth): + + ## Some (ancient) servers don't like UTF-8 binary auth with Digest authentication. + ## An example are old SabreDAV based servers. Not sure about UTF-8 and Basic Auth, + ## but likely the same. so retry if password is a bytes sequence and not a string + ## (see commit 13a4714, which introduced this regression) + + auth_type = r.headers['WWW-Authenticate'] + auth_type = auth_type[0:auth_type.find(" ")] + + if hasattr(self.password, 'decode'): + if auth_type == 'Basic': + self.auth = requests.auth.HTTPBasicAuth(self.username, self.password.decode()) + elif auth_type == 'Digest': + self.auth = requests.auth.HTTPDigestAuth(self.username, self.password.decode()) + self.username = None self.password = None return self.request(url, method, body, headers) |