Merge branch 'main' into avm99963-monorail

Merged commit 34d8229ae2b51fb1a15bd208e6fe6185c94f6266

GitOrigin-RevId: 7ee0917f93a577e475f8e09526dd144d245593f4
diff --git a/framework/template_helpers.py b/framework/template_helpers.py
index 7ebb7e2..d360054 100644
--- a/framework/template_helpers.py
+++ b/framework/template_helpers.py
@@ -1,7 +1,6 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file or at
-# https://developers.google.com/open-source/licenses/bsd
+# Copyright 2016 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
 
 """Some utility classes for interacting with templates."""
 
@@ -9,12 +8,14 @@
 from __future__ import print_function
 from __future__ import absolute_import
 
-import cgi
-import cStringIO
+try:
+  import html
+except ImportError:
+  import cgi as html
 from six.moves import http_client
+from six.moves import StringIO
 import logging
 import time
-import types
 
 import ezt
 import six
@@ -119,18 +120,14 @@
   return template
 
 
-class cStringIOUnicodeWrapper(object):
-  """Wrapper on cStringIO.StringIO that encodes unicode as UTF-8 as it goes."""
+class StringIOUnicodeWrapper(object):
+  """Wrapper on io.StringIO that encodes unicode as UTF-8 as it goes."""
 
   def __init__(self):
-    self.buffer = cStringIO.StringIO()
+    self.buffer = StringIO()
 
   def write(self, s):
-    if isinstance(s, six.text_type):
-      utf8_s = s.encode('utf-8')
-    else:
-      utf8_s = s
-    self.buffer.write(utf8_s)
+    self.buffer.write(six.ensure_str(s))
 
   def getvalue(self):
     return self.buffer.getvalue()
@@ -157,20 +154,6 @@
     if content_type:
       response.content_type = content_type
 
-    response.status = data.get('http_response_code', http_client.OK)
-    whole_page = self.GetResponse(data)
-    if data.get('prevent_sniffing'):
-      for sniff_pattern, sniff_replacement in SNIFFABLE_PATTERNS.items():
-        whole_page = whole_page.replace(sniff_pattern, sniff_replacement)
-    start = time.time()
-    response.write(whole_page)
-    logging.info('wrote response in %dms', int((time.time() - start) * 1000))
-
-  def WriteFlaskResponse(self, response, data, content_type=None):
-    """Write the parsed and filled in template to http server."""
-    if content_type:
-      response.content_type = content_type
-
     response.status_code = data.get('http_response_code', http_client.OK)
     whole_page = self.GetResponse(data)
     if data.get('prevent_sniffing'):
@@ -184,7 +167,7 @@
     """Generate the text from the template and return it as a string."""
     template = self.GetTemplate()
     start = time.time()
-    buf = cStringIOUnicodeWrapper()
+    buf = StringIOUnicodeWrapper()
     template.generate(buf, data)
     whole_page = buf.getvalue()
     logging.info('rendering took %dms', int((time.time() - start) * 1000))
@@ -311,7 +294,7 @@
     page_data: Template data which may include a 'labels' field.
   """
   label_list = page_data.get('labels', [])
-  if isinstance(label_list, types.StringTypes):
+  if isinstance(label_list, six.string_types):
     label_list = [label.strip() for label in page_data['labels'].split(',')]
 
   for i in range(len(label_list)):
@@ -334,7 +317,7 @@
     """Return a string that can be used in an HTML email body."""
     if self.tag == 'a' and self.href:
       return '<a href="%s">%s</a>' % (
-          cgi.escape(self.href, quote=True),
-          cgi.escape(self.content, quote=True))
+          html.escape(self.href,
+                      quote=True), html.escape(self.content, quote=True))
 
-    return cgi.escape(self.content, quote=True)
+    return html.escape(self.content, quote=True)