Python 3: port tests in cookie-store (#24531)

Co-authored-by: Robert Ma <robertma@chromium.og>
diff --git a/cookie-store/resources/cookie_helper.py b/cookie-store/resources/cookie_helper.py
index cf48f26..b88b25c 100755
--- a/cookie-store/resources/cookie_helper.py
+++ b/cookie-store/resources/cookie_helper.py
@@ -18,52 +18,76 @@
 #   Used to set cookies from an HTTP response header context.
 #
 # The response has 200 status and content-type: text/plain; charset=<charset>
-import cgi, encodings, os, re, sys, urllib
+import encodings, re
+
+from six import PY3
+
+from six.moves.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(r'[;\0-\x1f\x7f]');
-DISALLOWED_IN_HEADER_RE = re.compile(r'[\0-\x1f\x7f]');
+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 ('utf-8', 'iso-8859-1',)
+    for charset in (u'utf-8', u'iso-8859-1',)
 }
 
+def quote_str(cookie_str):
+  if PY3:
+    return isomorphic_encode(quote(isomorphic_decode(cookie_str), u'', encoding=u'iso-8859-1'))
+  else:
+    return quote(cookie_str, b'')
+
+def parse_qs_str(query_str):
+  if PY3:
+    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
+  else:
+    return parse_qs(query_str, keep_blank_values=True)
+
 def main(request, response):
   assert request.method in (
-      'GET',
-      'POST',
-  ), 'request method was neither GET nor POST: %r' % request.method
-  qd = (request.url.split('#')[0].split('?', 1) + [''])[1]
-  if request.method == 'POST':
-    qd += '&' + request.body
-  args = cgi.parse_qs(qd, keep_blank_values = True)
-  charset = encodings.codecs.lookup(args.get('charset', ['utf-8'])[-1]).name
+      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 = [('content-type', 'text/plain; charset=' + charset)]
+  headers = [(b'content-type', b'text/plain; charset=' + isomorphic_encode(charset))]
   body = []
-  if request.method == 'POST':
-    for set_cookie in args.get('set-cookie', []):
-      if '=' in set_cookie.split(';', 1)[0]:
-        name, rest = set_cookie.split('=', 1)
+  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, 'name had disallowed characters: %r' % name
+        ) is None, b'name had disallowed characters: %r' % name
       else:
         rest = set_cookie
       assert re.search(
           DISALLOWED_IN_HEADER_RE,
           rest
-      ) is None, 'rest had disallowed characters: %r' % rest
-      headers.append(('set-cookie', set_cookie))
-      body.append('set-cookie=' + urllib.quote(set_cookie, ''))
+      ) 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('cookie')
+    cookie = request.headers.get(b'cookie')
     if cookie is not None:
-      body.append('cookie=' + urllib.quote(cookie, ''))
-  body = '\r\n'.join(body)
-  headers.append(('content-length', str(len(body))))
+      body.append(b'cookie=' + quote_str(cookie))
+  body = b'\r\n'.join(body)
+  headers.append((b'content-length', len(body)))
   return 200, headers, body