Bug 1296240 - AttributeError: 'ExtendedHTTPDigestAuth' object has no attribute 'num_401_calls'
AttributeError: 'ExtendedHTTPDigestAuth' object has no attribute 'num_401_calls'
Product: Red Hat OpenStack
Classification: Red Hat
Component: python-requests (Show other bugs)
7.0 (Kilo)
Unspecified Unspecified
medium Severity medium
: ---
: 7.0 (Kilo)
Assigned To: Lon Hohberger
Shai Revivo
: ZStream
Depends On:
  Show dependency treegraph
Reported: 2016-01-06 11:42 EST by David Hill
Modified: 2017-07-24 13:07 EDT (History)
8 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2017-01-17 08:25:25 EST
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)

  None (edit)
Description David Hill 2016-01-06 11:42:38 EST
Description of problem:
When trying to connect to a site using FQDN instead of IP, the script will fail with the following trace:

CMD = get_stats.py /v1/cluster/stats?interval=5min&stime=2016-01-06T15:21:46Z
Traceback (most recent call last):
  File "get_stats.py", line 36, in <module>
    resp = requests.get(uri, headers=headers, auth=authDigest)
  File "/usr/lib/python2.7/site-packages/requests/api.py", line 69, in get
    return request('get', url, params=params, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/api.py", line 50, in request
    response = session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 465, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 594, in send
    history = [resp for resp in gen] if allow_redirects else []
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 196, in resolve_redirects
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 579, in send
    r = dispatch_hook('response', hooks, r, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/hooks.py", line 41, in dispatch_hook
    _hook_data = hook(hook_data, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/auth.py", line 175, in handle_401
    self.num_401_calls += 1
AttributeError: 'ExtendedHTTPDigestAuth' object has no attribute 'num_401_calls'

The following patch fixes this issue:

The scripts are running on a virtual guest.   Not on the openstack nodes.
The application responded to your questions with the following:

Yes, the issue is when using FQDN.

>diff -u ofc.auth.py auth.py
--- ofc.auth.py 2016-01-05 19:59:29.076607657 +0000
+++ auth.py     2015-11-25 02:35:41.677029892 +0000
@@ -170,6 +170,9 @@
         num_401_calls = getattr(self, 'num_401_calls', 1)
         s_auth = r.headers.get('www-authenticate', '')

+       #To fix the FQDN issue
+       self.num_401_calls = 1
         if 'digest' in s_auth.lower() and num_401_calls < 2

             self.num_401_calls += 1

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. Try to connect to a host using FQDN instead of IP and add authentication over that

Actual results:
Fails with AttributeError: 'ExtendedHTTPDigestAuth' object has no attribute 'num_401_calls'

Expected results:

Additional info:
Comment 3 Lon Hohberger 2016-02-09 14:22:29 EST
This looks like a bug in whatever's calling in to requests.

AttributeError: 'ExtendedHTTPDigestAuth' object has no attribute 'num_401_calls'

It looks like something's importing requests.auth HTTPDigest to create ExtendedHTTPDigestAuth class but not calling the __init__ function for HTTPDigestAuth, which sets self.num_401_calls to 1.
Comment 4 Lon Hohberger 2016-02-09 14:29:42 EST
class HTTPDigestAuth(AuthBase):
    """Attaches HTTP Digest Authentication to the given Request object."""
    def __init__(self, username, password):
        self.username = username
        self.password = password
        self.last_nonce = ''
        self.nonce_count = 0
        self.chal = {}
        self.pos = None
        self.num_401_calls = 1


My guess is get_stats.py is creating this derived object and simply needs something like:

class ExtendedHTTPDigestAuth(HTTPDigestAuth):
    def __init__(self, username, password ... ):
        # ADD THIS LINE
        super(ExtendedHTTPDigestAuth, self).__init__(username, password)
        # ^^^

This doesn't look like a bug in requests.

Note You need to log in before you can comment on or make changes to this bug.