Handles given HTTP request.

def HandleRequest(self, request):
    """Handles given HTTP request."""
    impersonated_username = config.CONFIG["AdminUI.debug_impersonate_user"]
    if impersonated_username:
      logging.info("Overriding user as %s", impersonated_username)
      request.user = config.CONFIG["AdminUI.debug_impersonate_user"]

    if not aff4_users.GRRUser.IsValidUsername(request.user):
      return self._BuildResponse(
          403, dict(message="Invalid username: %s" % request.user))

    try:
      router, method_metadata, args = self._router_matcher.MatchRouter(request)
    except access_control.UnauthorizedAccess as e:
      error_message = str(e)
      logging.exception("Access denied to %s (%s): %s", request.path,
                        request.method, e)

      additional_headers = {
          "X-GRR-Unauthorized-Access-Reason": error_message.replace("\n", ""),
          "X-GRR-Unauthorized-Access-Subject": utils.SmartStr(e.subject)
      }
      return self._BuildResponse(
          403,
          dict(
              message="Access denied by ACL: %s" % error_message,
              subject=utils.SmartStr(e.subject)),
          headers=additional_headers)

    except ApiCallRouterNotFoundError as e:
      error_message = str(e)
      return self._BuildResponse(404, dict(message=error_message))
    except werkzeug_exceptions.MethodNotAllowed as e:
      error_message = str(e)
      return self._BuildResponse(405, dict(message=error_message))
    except Error as e:
      logging.exception("Can't match URL to router/method: %s", e)

      return self._BuildResponse(
          500, dict(message=str(e), traceBack=traceback.format_exc()))

    request.method_metadata = method_metadata
    request.parsed_args = args

    # SetUID() is called here so that ACL checks done by the router do not
    # clash with datastore ACL checks.
    # TODO(user): increase token expiry time.
    token = self.BuildToken(request, 60).SetUID()

    if data_store.AFF4Enabled():
      # TODO:
      # AFF4 edge case: if a user is issuing a request, before they are created
      # using CreateGRRUser (e.g. in E2E tests or with single sign-on),
      # AFF4's ReadGRRUsers will NEVER contain the user, because the creation
      # done in the following lines does not add the user to the /users/
      # collection. Furthermore, subsequent CreateGrrUserHandler calls fail,
      # because the user technically already exists.

      # We send a blind-write request to ensure that the user object is created
      # for a user specified by the username.
      user_urn = rdfvalue.RDFURN("aff4:/users/").Add(request.user)
      # We can't use conventional AFF4 interface, since aff4.FACTORY.Create will
      # create a new version of the object for every call.
      with data_store.DB.GetMutationPool() as pool:
        pool.MultiSet(
            user_urn, {
                aff4_users.GRRUser.SchemaCls.TYPE:
                    [aff4_users.GRRUser.__name__],
                aff4_users.GRRUser.SchemaCls.LAST:
                    [rdfvalue.RDFDatetime.Now().SerializeToDataStore()]
            },
            replace=True)

    if data_store.RelationalDBEnabled():
      data_store.REL_DB.WriteGRRUser(request.user)

    handler = None
    try:
      # ACL checks are done here by the router. If this method succeeds (i.e.
      # does not raise), then handlers run without further ACL checks (they're
      # free to do some in their own implementations, though).
      handler = getattr(router, method_metadata.name)(args, token=token)

      if handler.args_type != method_metadata.args_type:
        raise RuntimeError("Handler args type doesn't match "
                           "method args type: %s vs %s" %
                           (handler.args_type, method_metadata.args_type))

      binary_result_type = (
          api_call_router.RouterMethodMetadata.BINARY_STREAM_RESULT_TYPE)

      if (handler.result_type != method_metadata.result_type and
          not (handler.result_type is None and
               method_metadata.result_type == binary_result_type)):
        raise RuntimeError("Handler result type doesn't match "
                           "method result type: %s vs %s" %
                           (handler.result_type, method_metadata.result_type))

      # HEAD method is only used for checking the ACLs for particular API
      # methods.
      if request.method == "HEAD":
        # If the request would return a stream, we add the Content-Length
        # header to the response.
        if (method_metadata.result_type ==
            method_metadata.BINARY_STREAM_RESULT_TYPE):
          binary_stream = handler.Handle(args, token=token)
          return self._BuildResponse(
              200, {"status": "OK"},
              method_name=method_metadata.name,
              no_audit_log=method_metadata.no_audit_log_required,
              content_length=binary_stream.content_length,
              token=token)
        else:
          return self._BuildResponse(
              200, {"status": "OK"},
              method_name=method_metadata.name,
              no_audit_log=method_metadata.no_audit_log_required,
              token=token)

      if (method_metadata.result_type ==
          method_metadata.BINARY_STREAM_RESULT_TYPE):
        binary_stream = handler.Handle(args, token=token)
        return self._BuildStreamingResponse(
            binary_stream, method_name=method_metadata.name)
      else:
        format_mode = GetRequestFormatMode(request, method_metadata)
        result = self.CallApiHandler(handler, args, token=token)
        rendered_data = self._FormatResultAsJson(
            result, format_mode=format_mode)

        return self._BuildResponse(
            200,
            rendered_data,
            method_name=method_metadata.name,
            no_audit_log=method_metadata.no_audit_log_required,
            token=token)
    except access_control.UnauthorizedAccess as e:
      error_message = str(e)
      logging.warning("Access denied for %s (HTTP %s %s): %s",
                      method_metadata.name, request.method, request.path,
                      error_message)

      additional_headers = {
          "X-GRR-Unauthorized-Access-Reason": error_message.replace("\n", ""),
          "X-GRR-Unauthorized-Access-Subject": utils.SmartStr(e.subject)
      }
      return self._BuildResponse(
          403,
          dict(
              message="Access denied by ACL: %s" % error_message,
              subject=utils.SmartStr(e.subject)),
          headers=additional_headers,
          method_name=method_metadata.name,
          no_audit_log=method_metadata.no_audit_log_required,
          token=token)
    except api_call_handler_base.ResourceNotFoundError as e:
      error_message = str(e)
      return self._BuildResponse(
          404,
          dict(message=error_message),
          method_name=method_metadata.name,
          no_audit_log=method_metadata.no_audit_log_required,
          token=token)
    except NotImplementedError as e:
      error_message = str(e)
      return self._BuildResponse(
          501,
          dict(message=error_message),
          method_name=method_metadata.name,
          no_audit_log=method_metadata.no_audit_log_required,
          token=token)
    except Exception as e:  # pylint: disable=broad-except
      error_message = str(e)
      logging.exception("Error while processing %s (%s) with %s: %s",
                        request.path, request.method,
                        handler.__class__.__name__, e)
      return self._BuildResponse(
          500,
          dict(message=error_message, traceBack=traceback.format_exc()),
          method_name=method_metadata.name,
          no_audit_log=method_metadata.no_audit_log_required,
          token=token)