diff options
Diffstat (limited to 'wsgitools/digest.py')
-rw-r--r-- | wsgitools/digest.py | 62 |
1 files changed, 42 insertions, 20 deletions
diff --git a/wsgitools/digest.py b/wsgitools/digest.py index 53b7dea..964fa0a 100644 --- a/wsgitools/digest.py +++ b/wsgitools/digest.py @@ -60,28 +60,50 @@ def parse_digest_response(data, ret=None): ... except ValueError: ... print("ValueError") ValueError + >>> # backslashes: doc string, eval => two backslashes + >>> parse_digest_response('backslash="\\\\\\\\"') + {'backslash': '\\\\'} + >>> parse_digest_response('foo="quo\\\\"te"') + {'foo': 'quo"te'} """ assert isinstance(data, str) - if ret is None: - ret = {} - data = data.strip() - key, rest = data.split('=', 1) # raises ValueError - if rest.startswith('"'): - rest = rest[1:] - value, rest = rest.split('"', 1) # raises ValueError - if not rest: - ret[key] = value - return ret - if rest[0] != ',': - raise ValueError("invalid digest response") - rest = rest[1:] - else: - if ',' not in rest: - ret[key] = rest - return ret - value, rest = rest.split(',' , 1) - ret[key] = value - return parse_digest_response(rest, ret) + result = dict() + while True: + data = data.strip() + key, data = data.split('=', 1) # raises ValueError + if data.startswith('"'): + data = data[1:] + value = "" + while True: + part, data = data.split('"', 1) # raises ValueError + # how many consecutive backslashes did we see? + escape = -1 # the first iteration does not indicate a backslash + for part in part.split('\\'): + escape += 1 # backslash before part + if escape > 2: + value += "\\" + escape -= 2 + if part: + escape = 0 + value += part + if escape == 2: + value += "\\" + elif escape == 1: + value += '"' + continue + break + result[key] = value + if not data: + return result + if data[0] != ",": + raise ValueError("invalid digest response") + data = data[1:] + else: + if ',' not in data: + result[key] = data + return result + value, data = data.split(',', 1) + result[key] = value class AuthenticationRequired(Exception): """ |