summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--wsgitools/digest.py17
1 files changed, 15 insertions, 2 deletions
diff --git a/wsgitools/digest.py b/wsgitools/digest.py
index 964fa0a..83fbd65 100644
--- a/wsgitools/digest.py
+++ b/wsgitools/digest.py
@@ -114,6 +114,19 @@ class AuthenticationRequired(Exception):
class ProtocolViolation(AuthenticationRequired):
pass
+def format_digest(mapping):
+ """internal
+
+ @type mapping: {str: str}
+ @rtype: str
+ """
+ assert isinstance(mapping, dict)
+ result = ((key, value if value.isalnum() else
+ '"%s"' % value.replace('\\', '\\\\').replace('"', '\\"'))
+ for key, value in mapping.items())
+ result = map("%s=%s".__mod__, result)
+ return ", ".join(result)
+
class StaleNonce(AuthenticationRequired):
pass
@@ -752,7 +765,7 @@ class AuthDigestMiddleware:
digest["qop"] = "auth"
digest["cnonce"] = credentials["cnonce"] # no KeyError
digest["rspauth"] = self.auth_response(credentials, "")
- challenge = ", ".join(map('%s="%s"'.__mod__, digest.items()))
+ challenge = format_digest(digest)
headers.append(("Authentication-Info", challenge))
return start_response(status, headers, exc_info)
return self.app(environ, modified_start_response)
@@ -806,7 +819,7 @@ class AuthDigestMiddleware:
qop="auth")
if isinstance(exception, StaleNonce):
digest["stale"] = "TRUE"
- challenge = ", ".join(map('%s="%s"'.__mod__, digest.items()))
+ challenge = format_digest(digest)
return ("WWW-Authenticate", "Digest %s" % challenge)
def authorization_required(self, environ, start_response, exception):