Bug 1296240 - AttributeError: 'ExtendedHTTPDigestAuth' object has no attribute 'num_401_calls'
Summary: AttributeError: 'ExtendedHTTPDigestAuth' object has no attribute 'num_401_calls'
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat OpenStack
Classification: Red Hat
Component: python-requests
Version: 7.0 (Kilo)
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: ---
: 7.0 (Kilo)
Assignee: Lon Hohberger
QA Contact: Shai Revivo
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2016-01-06 16:42 UTC by David Hill
Modified: 2020-12-11 12:01 UTC (History)
8 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2017-01-17 13:25:25 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)

Description David Hill 2016-01-06 16:42:38 UTC
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
    **adapter_kwargs
  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):
2.7.0-1

How reproducible:
Always

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

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


Expected results:
Succeeds


Additional info:

Comment 3 Lon Hohberger 2016-02-09 19:22:29 UTC
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 19:29:42 UTC
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.