HTTPDigestAuth: Empty qop header in server challenge results in Authorization: None

This is a bit of a weird one, and I'm fairly certain the server is misbehaving slightly, but since I have less control over that:

When issuing a request with the following:

```
        response = requests.post(url,
            auth=HTTPDigestAuth('admin', 'foobar'))
```

The server returns back a challenge with the following `WWW-Authenticate` header:

```
reply: 'HTTP/1.1 401 Unauthorized\r\n'
header: Server: nginx
header: Date: Sat, 05 Dec 2015 02:08:43 GMT
header: Content-Type: text/html; charset=utf-8
header: Content-Length: 188
header: Connection: keep-alive
header: WWW-Authenticate: Digest realm="foobar_api_auth", qop="", nonce="a12059eaaad0b86ece8f62f04cbafed6", algorithm="MD5", stale="false"
```

Note the `qop` header with an empty value. That doesn't appear to be valid per RFC 2617:

> ```
>   qop-value         = "auth" | "auth-int" | token
> ```

That being said, RFC 2617 does specify that unrecognised values MUST be ignored. Instead, it looks like requests drops the entire authorization header:

```

        if qop is None:
            respdig = KD(HA1, "%s:%s" % (nonce, HA2))
        elif qop == 'auth' or 'auth' in qop.split(','):
            noncebit = "%s:%s:%s:%s:%s" % (
                nonce, ncvalue, cnonce, 'auth', HA2
                )
            respdig = KD(HA1, noncebit)
        else:
            # XXX handle auth-int.
            return None
```

This results in the following being sent back to the challenge:

```
send: 'POST /json HTTP/1.1\r\nHost: foo.com\r\nContent-Length: 94\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python-requests/2.8.1\r\nConnection: keep-alive\r\nContent-Type: application/json\r\nAuthorization: None\r\n\r\n{"data": "more}'
```

I'd be more than happy to work on a PR for this issue, but would like to confirm that a PR that updates the handling of `qop` to be tolerant to unrecognized tokens/characters would be acceptable. Arguably, the server should be omitting the `qop` header completely, but RFC compliance in requests would probably make it more tolerant to misbehaving servers like this one.

Thanks!


Yeah, so the server is wrong here. However, I think we can get to a place where we roughly DTRT here, by assuming that if `qop` is any falsy value then we should enter the first block. That'll cover this case as well.

I'd accept a PR that makes this change.


Awesome! I'll have something up this weekend.

I did notice that httpbin doesn't really allow much control over the qop value - it will pretty much force it to be either `auth` or `auth-int`:

```
@app.route('/digest-auth/<qop>/<user>/<passwd>')
def digest_auth(qop=None, user='user', passwd='passwd'):
    """Prompts the user for authorization using HTTP Digest auth"""
    if qop not in ('auth', 'auth-int'):
        qop = None
```

I'd be happy to write some unit tests that cover the PR, but I'd probably have to make httpbin more flexible as well. I'm kind of concerned about doing that - any unit tests that are written for requests that require a particular updated version of httpbin are bound to be brittle.

Still, if you think it'd be useful, I can put up a PR for httpbin as well.


Yeah, for now we'll consider the tests a todo: we'll spin back to them when I spend time making more investment on our test suite. 


Cool. If you'd ever like some help with that, let me know. I do some work on test suites from time to time :smile: