Merge branch 'main' into avm99963-monorail

Merged commit 34d8229ae2b51fb1a15bd208e6fe6185c94f6266

GitOrigin-RevId: 7ee0917f93a577e475f8e09526dd144d245593f4
diff --git a/framework/monorailrequest.py b/framework/monorailrequest.py
index 7fe2918..52f3e52 100644
--- a/framework/monorailrequest.py
+++ b/framework/monorailrequest.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.
 
 """Classes to hold information parsed from a request.
 
@@ -19,13 +18,12 @@
 from six.moves import urllib
 
 import ezt
+import flask
 import six
 
 from google.appengine.api import app_identity
 from google.appengine.api import oauth
 
-import webapp2
-
 import settings
 from businesslogic import work_env
 from features import features_constants
@@ -39,12 +37,12 @@
 from framework import profiler
 from framework import sql
 from framework import template_helpers
-from proto import api_pb2_v1
+from mrproto import api_pb2_v1
 from tracker import tracker_bizobj
 from tracker import tracker_constants
 
 
-_HOSTPORT_RE = re.compile('^[-a-z0-9.]+(:\d+)?$', re.I)
+_HOSTPORT_RE = re.compile(r'^[-a-z0-9.]+(:\d+)?$', re.I)
 
 
 # TODO(jrobbins): Stop extending MonorailContext and change whole servlet
@@ -231,63 +229,6 @@
     self.viewed_user_auth = authdata.AuthData()
 
   def ParseRequest(self, request, services, do_user_lookups=True):
-    """Parse tons of useful info from the given request object.
-
-    Args:
-      request: webapp2 Request object w/ path and query params.
-      services: connections to backend servers including DB.
-      do_user_lookups: Set to False to disable lookups during testing.
-    """
-    with self.profiler.Phase('basic parsing'):
-      self.request = request
-      self.request_path = request.path
-      self.current_page_url = request.url
-      self.current_page_url_encoded = urllib.parse.quote_plus(
-          self.current_page_url)
-
-      # Only accept a hostport from the request that looks valid.
-      if not _HOSTPORT_RE.match(request.host):
-        raise exceptions.InputException(
-            'request.host looks funny: %r', request.host)
-
-      logging.info('Request: %s', self.current_page_url)
-
-    with self.profiler.Phase('path parsing'):
-      (viewed_user_val, self.project_name, self.hotlist_id,
-       self.hotlist_name) = _ParsePathIdentifiers(self.request_path)
-      self.viewed_username = _GetViewedEmail(
-          viewed_user_val, self.cnxn, services)
-    with self.profiler.Phase('qs parsing'):
-      self._ParseQueryParameters()
-    with self.profiler.Phase('overrides parsing'):
-      self._ParseFormOverrides()
-
-    if not self.project:  # It can be already set in unit tests.
-      self._LookupProject(services)
-    if self.project_id and services.config:
-      self.config = services.config.GetProjectConfig(self.cnxn, self.project_id)
-
-    if do_user_lookups:
-      if self.viewed_username:
-        self._LookupViewedUser(services)
-      self._LookupLoggedInUser(services)
-
-    if not self.hotlist:
-      self._LookupHotlist(services)
-
-    if self.query is None:
-      self.query = self._CalcDefaultQuery()
-
-    prod_debug_allowed = self.perms.HasPerm(
-        permissions.VIEW_DEBUG, self.auth.user_id, None)
-    self.debug_enabled = (request.params.get('debug') and
-                          (settings.local_mode or prod_debug_allowed))
-    # temporary option for perf testing on staging instance.
-    if request.params.get('disable_cache'):
-      if settings.local_mode or 'staging' in request.host:
-        self.use_cached_searches = False
-
-  def ParseFlaskRequest(self, request, services, do_user_lookups=True):
     """Parse tons of useful info from the given flask request object.
 
     Args:
@@ -300,7 +241,7 @@
       self.request_path = request.base_url[len(request.host_url) - 1:]
       self.current_page_url = request.url
       self.current_page_url_encoded = urllib.parse.quote_plus(
-          self.current_page_url)
+          six.ensure_str(self.current_page_url))
 
       # Only accept a hostport from the request that looks valid.
       if not _HOSTPORT_RE.match(request.host):
@@ -502,10 +443,10 @@
             self.cnxn, self.viewed_username, services, autocreate=False)
     except exceptions.NoSuchUserException:
       logging.info('could not find user %r', self.viewed_username)
-      webapp2.abort(404, 'user not found')
+      flask.abort(404, 'user not found')
 
     if not self.viewed_user_auth.user_id:
-      webapp2.abort(404, 'user not found')
+      flask.abort(404, 'user not found')
 
   def _LookupProject(self, services):
     """Get information about the current project (if any) from the request.
@@ -530,7 +471,7 @@
           self.hotlist_id = hotlist_id_dict[(
               self.hotlist_name, self.viewed_user_auth.user_id)]
         except KeyError:
-          webapp2.abort(404, 'invalid hotlist')
+          flask.abort(404, 'invalid hotlist')
 
       if not self.hotlist_id:
         logging.info('no hotlist_id or bad hotlist_name, so no hotlist')
@@ -540,7 +481,7 @@
         if not self.hotlist or (
             self.viewed_user_auth.user_id and
             self.viewed_user_auth.user_id not in self.hotlist.owner_ids):
-          webapp2.abort(404, 'invalid hotlist')
+          flask.abort(404, 'invalid hotlist')
 
   def _LookupLoggedInUser(self, services):
     """Get information about the signed-in user (if any) from the request."""
@@ -601,7 +542,7 @@
       value = self.request.params.get(query_param_name)
     else:
       value = self.request.values.get(query_param_name)
-    assert value is None or isinstance(value, six.text_type)
+    assert value is None or isinstance(value, six.string_types)
     using_default = value is None
     if using_default:
       value = default_value
@@ -635,8 +576,10 @@
 
   def GetPositiveIntParam(self, query_param_name, default_value=None):
     """Returns 0 if the user-provided value is less than 0."""
-    return max(self.GetIntParam(query_param_name, default_value=default_value),
-               0)
+    value = self.GetIntParam(query_param_name, default_value=default_value)
+    if value is None:
+      return 0
+    return max(value, 0)
 
   def GetListParam(self, query_param_name, default_value=None):
     """Get a list of strings from the URL or default."""
@@ -742,7 +685,7 @@
     viewed_email = services.user.LookupUserEmail(cnxn, viewed_userid)
     if not viewed_email:
       logging.info('userID %s not found', viewed_userid)
-      webapp2.abort(404, 'user not found')
+      flask.abort(404, 'user not found')
   except ValueError:
     viewed_email = viewed_user_val