Fix hangs on streaming uploads with HTTPDigestAuth

When using Digest Authentication, the client resends the same request
after the server responds with the 401 "Unauthorized". However, when
doing streaming uploads, it gets stuck because the body data (a
file-like object) is already consumed at the initial request.

The patch fixes this by rewinding the file-like object before
resending the request.
This commit is contained in:
Akira Kitada
2013-11-25 22:29:53 +09:00
parent 3327652623
commit 3a9d9f2279
+9
View File
@@ -63,6 +63,7 @@ class HTTPDigestAuth(AuthBase):
self.last_nonce = ''
self.nonce_count = 0
self.chal = {}
self.pos = None
def build_digest_header(self, method, url):
@@ -150,6 +151,10 @@ class HTTPDigestAuth(AuthBase):
def handle_401(self, r, **kwargs):
"""Takes the given response and tries digest-auth, if needed."""
if self.pos is not None:
# Rewind the file position indicator of the body to where
# it was to resend the request.
r.request.body.seek(self.pos)
num_401_calls = getattr(self, 'num_401_calls', 1)
s_auth = r.headers.get('www-authenticate', '')
@@ -181,5 +186,9 @@ class HTTPDigestAuth(AuthBase):
# If we have a saved nonce, skip the 401
if self.last_nonce:
r.headers['Authorization'] = self.build_digest_header(r.method, r.url)
try:
self.pos = r.body.tell()
except AttributeError:
pass
r.register_hook('response', self.handle_401)
return r