diff options
Diffstat (limited to 'testing/web-platform/tests/cookie-store/resources/cookie_helper.py')
-rw-r--r-- | testing/web-platform/tests/cookie-store/resources/cookie_helper.py | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/testing/web-platform/tests/cookie-store/resources/cookie_helper.py b/testing/web-platform/tests/cookie-store/resources/cookie_helper.py new file mode 100644 index 0000000000..71dd8b82ee --- /dev/null +++ b/testing/web-platform/tests/cookie-store/resources/cookie_helper.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +# Active wptserve handler for cookie operations. +# +# This must support the following requests: +# +# - GET with the following query parameters: +# - charset: (optional) character set for response (default: utf-8) +# A cookie: request header (if present) is echoed in the body with a +# cookie= prefix followed by the urlencoded bytes from the header. +# Used to inspect the cookie jar from an HTTP request header context. +# - POST with form-data in the body and the following query-or-form parameters: +# - set-cookie: (optional; repeated) echoed in the set-cookie: response +# header and also echoed in the body with a set-cookie= prefix +# followed by the urlencoded bytes from the parameter; multiple occurrences +# are CRLF-delimited. +# Used to set cookies from an HTTP response header context. +# +# The response has 200 status and content-type: text/plain; charset=<charset> +import encodings, re + +from urllib.parse import parse_qs, quote + +from wptserve.utils import isomorphic_decode, isomorphic_encode + +# NOTE: These are intentionally very lax to permit testing +DISALLOWED_IN_COOKIE_NAME_RE = re.compile(br'[;\0-\x1f\x7f]') +DISALLOWED_IN_HEADER_RE = re.compile(br'[\0-\x1f\x7f]') + +# Ensure common charset names do not end up with different +# capitalization or punctuation +CHARSET_OVERRIDES = { + encodings.codecs.lookup(charset).name: charset + for charset in (u'utf-8', u'iso-8859-1',) +} + +def quote_str(cookie_str): + return isomorphic_encode(quote(isomorphic_decode(cookie_str), u'', encoding=u'iso-8859-1')) + +def parse_qs_str(query_str): + args = parse_qs(isomorphic_decode(query_str), keep_blank_values=True, encoding=u'iso-8859-1') + binary_args = {} + for key, val in args.items(): + binary_args[isomorphic_encode(key)] = [isomorphic_encode(x) for x in val] + return binary_args + +def main(request, response): + assert request.method in ( + u'GET', + u'POST', + ), u'request method was neither GET nor POST: %r' % request.method + qd = (isomorphic_encode(request.url).split(b'#')[0].split(b'?', 1) + [b''])[1] + if request.method == u'POST': + qd += b'&' + request.body + args = parse_qs_str(qd) + + charset = encodings.codecs.lookup([isomorphic_decode(x) for x in args.get(b'charset', [u'utf-8'])][-1]).name + charset = CHARSET_OVERRIDES.get(charset, charset) + headers = [(b'content-type', b'text/plain; charset=' + isomorphic_encode(charset))] + body = [] + if request.method == u'POST': + for set_cookie in args.get(b'set-cookie', []): + if b'=' in set_cookie.split(b';', 1)[0]: + name, rest = set_cookie.split(b'=', 1) + assert re.search( + DISALLOWED_IN_COOKIE_NAME_RE, + name + ) is None, b'name had disallowed characters: %r' % name + else: + rest = set_cookie + assert re.search( + DISALLOWED_IN_HEADER_RE, + rest + ) is None, b'rest had disallowed characters: %r' % rest + headers.append((b'set-cookie', set_cookie)) + body.append(b'set-cookie=' + quote_str(set_cookie)) + + else: + cookie = request.headers.get(b'cookie') + if cookie is not None: + body.append(b'cookie=' + quote_str(cookie)) + body = b'\r\n'.join(body) + headers.append((b'content-length', len(body))) + return 200, headers, body |