Skip to content

Commit f9a485d

Browse files
committed
Fix authentication to work with CouchDB 0.11.x.
CouchDB doesn't send a www-authenticate header any more so all we can do is assume it's basic auth and retry the request.
1 parent 30daaf9 commit f9a485d

File tree

1 file changed

+14
-17
lines changed

1 file changed

+14
-17
lines changed

couchdb/http.py

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,14 @@ def _retry():
210210

211211
# Handle authentication challenge
212212
if status == 401:
213-
auth_header = resp.getheader('www-authenticate', '')
214-
if auth_header:
215-
if self._authenticate(auth_header, headers, credentials):
216-
resp.read() # read the 401 response
217-
resp = _try_request()
218-
status = resp.status
213+
# Assume basic auth (CouchDB 0.11.x doesn't send a www-authenticate
214+
# header).
215+
authorization = basic_auth(credentials)
216+
if authorization:
217+
resp.read() # read the 401 response
218+
headers['Authorization'] = authorization
219+
resp = _try_request()
220+
status = resp.status
219221

220222
# Handle conditional response
221223
if status == 304 and method in ('GET', 'HEAD'):
@@ -301,17 +303,6 @@ def _clean_cache(self):
301303
ls = sorted(self.cache.iteritems(), key=cache_sort)
302304
self.cache = dict(ls[-CACHE_SIZE[0]:])
303305

304-
def _authenticate(self, info, headers, credentials):
305-
# Naive Basic authentication support
306-
match = re.match(r'''(\w*)\s+realm=['"]([^'"]+)['"]''', info)
307-
if match:
308-
scheme, realm = match.groups()
309-
if scheme.lower() == 'basic':
310-
headers['Authorization'] = 'Basic %s' % b64encode(
311-
'%s:%s' % credentials
312-
)
313-
return True
314-
315306
def _get_connection(self, url):
316307
scheme, host = urlsplit(url, 'http', False)[:2]
317308
self.lock.acquire()
@@ -425,6 +416,12 @@ def extract_credentials(url):
425416
return urlunsplit(parts), (username, password)
426417

427418

419+
def basic_auth(credentials):
420+
if credentials == (None, None):
421+
return None
422+
return 'Basic %s' % b64encode('%s:%s' % credentials)
423+
424+
428425
def quote(string, safe=''):
429426
if isinstance(string, unicode):
430427
string = string.encode('utf-8')

0 commit comments

Comments
 (0)