summaryrefslogtreecommitdiff
path: root/wsgitools/digest.py
diff options
context:
space:
mode:
Diffstat (limited to 'wsgitools/digest.py')
-rw-r--r--wsgitools/digest.py62
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):
"""