#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#




"""Helper CGI for Apiserver in the development app server.

This is a fake apiserver proxy that does simple transforms on requests that
come in to /_ah/api and then re-dispatches them to /_ah/spi.  It does not do
any authentication, quota checking, DoS checking, etc.

In addition, the proxy loads api configs from
/_ah/spi/BackendService.getApiConfigs prior to making the first call to the
backend at /_ah/spi and afterwards if app.yaml is changed.
"""

from __future__ import with_statement




import base64
import cgi
import cStringIO
import httplib
try:

  import json
except ImportError:

  import simplejson as json

import logging
import mimetools
import re


API_SERVING_PATTERN = '/_ah/api/.*'





SPI_ROOT_FORMAT = 'http://127.0.0.1:%s/_ah/spi/%s'


_API_REST_PATH_FORMAT = '{!name}/{!version}/%s'
_PATH_VARIABLE_PATTERN = r'[a-zA-Z_][a-zA-Z_.\d]*'
_RESERVED_PATH_VARIABLE_PATTERN = r'!' + _PATH_VARIABLE_PATTERN
_PATH_VALUE_PATTERN = r'[^:/?#\[\]{}]*'
_CORS_HEADER_ORIGIN = 'Origin'.lower()
_CORS_HEADER_REQUEST_METHOD = 'Access-Control-Request-Method'.lower()
_CORS_HEADER_REQUEST_HEADERS = 'Access-Control-Request-Headers'.lower()
_CORS_HEADER_ALLOW_ORIGIN = 'Access-Control-Allow-Origin'
_CORS_HEADER_ALLOW_METHODS = 'Access-Control-Allow-Methods'
_CORS_HEADER_ALLOW_HEADERS = 'Access-Control-Allow-Headers'
_CORS_ALLOWED_METHODS = frozenset(('DELETE', 'GET', 'PATCH', 'POST', 'PUT'))
_INVALID_ENUM_TEMPLATE = 'Invalid string value: %r. Allowed values: %r'


class RequestRejectionError(Exception):
  """Base class for rejected requests.

  To be raised when parsing the request values and comparing them against the
  generated discovery document.
  """

  def Message(self): raise NotImplementedError
  def Errors(self): raise NotImplementedError

  def ToJson(self):
    """JSON string representing the rejected value.

    Calling this will fail on the base class since it relies on Message and
    Errors being implemented on the class. It is up to a subclass to implement
    these methods.

    Returns:
      JSON string representing the rejected value.
    """
    return json.dumps({
        'error': {
            'errors': self.Errors(),
            'code': 400,
            'message': self.Message(),
        },
    })


class EnumRejectionError(RequestRejectionError):
  """Custom request rejection exception for enum values."""


  def __init__(self, parameter_name, value, allowed_values):
    """Constructor for EnumRejectionError.

    Args:
      parameter_name: String; the name of the enum parameter which had a value
        rejected.
      value: The actual value passed in for the enum. Usually string.
      allowed_values: List of strings allowed for the enum.
    """
    self.parameter_name = parameter_name
    self.value = value
    self.allowed_values = allowed_values


  def Message(self):
    """A descriptive message describing the error."""
    return _INVALID_ENUM_TEMPLATE % (self.value, self.allowed_values)



  def Errors(self):
    """A list containing the errors associated with the rejection.

    Intended to mimic those returned from an API in production in Google's API
    infrastructure.

    Returns:
      A list with a single element that is a dictionary containing the error
        information.
    """
    return [
        {
            'domain': 'global',
            'reason': 'invalidParameter',
            'message': self.Message(),
            'locationType': 'parameter',
            'location': self.parameter_name,
        },
    ]


class ApiRequest(object):
  """Simple data object representing an API request.

  Takes an app_server CGI request and environment in the constructor.
  Parses the request into convenient pieces and stores them as members.
  """
  API_PREFIX = '/_ah/api/'

  def __init__(self, base_env_dict, old_dev_appserver, request=None):
    """Constructor.

    Args:
      base_env_dict: Dictionary of CGI environment parameters.
      old_dev_appserver: used to call standard SplitURL method.
      request: AppServerRequest.  Can be None.
    """
    self.cgi_env = base_env_dict
    self.headers = {}
    self.http_method = base_env_dict['REQUEST_METHOD']
    self.port = base_env_dict['SERVER_PORT']
    if request:
      self.path, self.query = old_dev_appserver.SplitURL(request.relative_url)


      self.body = request.infile.read()
      for header in request.headers.headers:
        header_name, header_value = header.split(':', 1)
        self.headers[header_name.strip()] = header_value.strip()
    else:
      self.body = ''
      self.path = self.API_PREFIX
      self.query = ''
    assert self.path.startswith(self.API_PREFIX)
    self.path = self.path[len(self.API_PREFIX):]
    self.parameters = cgi.parse_qs(self.query, keep_blank_values=True)
    self.body_obj = json.loads(self.body) if self.body else {}
    self.request_id = None

  def _IsRpc(self):








    return self.path == 'rpc'


class DiscoveryApiProxy(object):
  """Proxies discovery service requests to a known cloud endpoint."""



  _DISCOVERY_PROXY_HOST = 'webapis-discovery.appspot.com'
  _STATIC_PROXY_HOST = 'webapis-discovery.appspot.com'
  _DISCOVERY_API_PATH_PREFIX = '/_ah/api/discovery/v1/'

  def _DispatchRequest(self, path, body):
    """Proxies GET request to discovery service API.

    Args:
      path: URL path relative to discovery service.
      body: HTTP POST request body.

    Returns:
      HTTP response body or None if it failed.
    """
    full_path = self._DISCOVERY_API_PATH_PREFIX + path
    headers = {'Content-type': 'application/json'}
    connection = httplib.HTTPSConnection(self._DISCOVERY_PROXY_HOST)
    try:
      connection.request('POST', full_path, body, headers)
      response = connection.getresponse()
      response_body = response.read()
      if response.status != 200:
        logging.error('Discovery API proxy failed on %s with %d.\r\n'
                      'Request: %s\r\nResponse: %s',
                      full_path, response.status, body, response_body)
        return None
      return response_body
    finally:
      connection.close()

  def GenerateDiscoveryDoc(self, api_config, api_format):
    """Generates a discovery document from an API file.

    Args:
      api_config: .api file contents as string.
      api_format: 'rest' or 'rpc' depending on the which kind of discvoery doc.

    Returns:
      Discovery doc as JSON string.

    Raises:
      ValueError: When api_format is invalid.
    """
    if api_format not in ['rest', 'rpc']:
      raise ValueError('Invalid API format')
    path = 'apis/generate/' + api_format
    request_dict = {'config': json.dumps(api_config)}
    request_body = json.dumps(request_dict)
    return self._DispatchRequest(path, request_body)

  def GenerateDirectory(self, api_configs):
    """Generates an API directory from a list of API files.

    Args:
      api_configs: list of strings which are the .api file contents.

    Returns:
      API directory as JSON string.
    """
    request_dict = {'configs': api_configs}
    request_body = json.dumps(request_dict)
    return self._DispatchRequest('apis/generate/directory', request_body)

  def GetStaticFile(self, path):
    """Returns static content via a GET request.

    Args:
      path: URL path after the domain.

    Returns:
      Tuple of (response, response_body):
        response: HTTPResponse object.
        response_body: Response body as string.
    """
    connection = httplib.HTTPSConnection(self._STATIC_PROXY_HOST)
    try:
      connection.request('GET', path, None, {})
      response = connection.getresponse()
      response_body = response.read()
    finally:
      connection.close()
    return response, response_body


class DiscoveryService(object):
  """Implements the local devserver discovery service.

     This has a static minimal version of the discoverable part of the
     discovery .api file.
     It only handles returning the discovery doc and directory, and ignores
     directory parameters to filter the results.

     The discovery docs/directory are created by calling a cloud endpoint
     discovery service to generate the discovery docs/directory from an .api
     file/set of .api files.
  """

  _GET_REST_API = 'apisdev.getRest'
  _GET_RPC_API = 'apisdev.getRpc'
  _LIST_API = 'apisdev.list'
  API_CONFIG = {
      'name': 'discovery',
      'version': 'v1',
      'methods': {
          'discovery.apis.getRest': {
              'path': 'apis/{api}/{version}/rest',
              'httpMethod': 'GET',
              'rosyMethod': _GET_REST_API,
          },
          'discovery.apis.getRpc': {
              'path': 'apis/{api}/{version}/rpc',
              'httpMethod': 'GET',
              'rosyMethod': _GET_RPC_API,
          },
          'discovery.apis.list': {
              'path': 'apis',
              'httpMethod': 'GET',
              'rosyMethod': _LIST_API,
          },
      }
  }

  def __init__(self, config_manager, api_request, outfile):
    """Initializes an instance of the DiscoveryService.

    Args:
      config_manager: an instance of ApiConfigManager.
      api_request: an instance of ApiRequest.
      outfile: the CGI file object to write the response to.
    """
    self._config_manager = config_manager
    self._params = json.loads(api_request.body or '{}')
    self._outfile = outfile
    self._discovery_proxy = DiscoveryApiProxy()

  def _SendSuccessResponse(self, response):
    """Sends an HTTP 200 json success response.

    Args:
      response: Response body as string to return.

    Returns:
      Sends back an HTTP 200 json success response.
    """
    headers = {'Content-Type': 'application/json; charset=UTF-8'}
    return SendCGIResponse('200', headers, response, self._outfile)

  def _GetRpcOrRest(self, api_format):
    """Sends back HTTP response with API directory.

    Args:
      api_format: Either 'rest' or 'rpc'. Sends CGI response containing
        the discovery doc for the api/version.

    Returns:
      None.
    """
    api = self._params['api']
    version = self._params['version']
    lookup_key = (api, version)
    api_config = self._config_manager.configs.get(lookup_key)
    if not api_config:
      logging.warn('No discovery doc for version %s of api %s', version, api)
      SendCGINotFoundResponse(self._outfile)
      return
    doc = self._discovery_proxy.GenerateDiscoveryDoc(api_config, api_format)
    if not doc:
      error_msg = ('Failed to convert .api to discovery doc for '
                   'version %s of api %s') % (version, api)
      logging.error('%s', error_msg)
      SendCGIErrorResponse(error_msg, self._outfile)
      return
    self._SendSuccessResponse(doc)

  def _GetRest(self):
    return self._GetRpcOrRest('rest')

  def _GetRpc(self):
    return self._GetRpcOrRest('rpc')

  def _List(self):
    """Sends HTTP response containing the API directory."""
    api_configs = []
    for api_config in self._config_manager.configs.itervalues():



      if not api_config == self.API_CONFIG:
        api_configs.append(json.dumps(api_config))
    directory = self._discovery_proxy.GenerateDirectory(api_configs)
    if not directory:
      logging.error('Failed to get API directory')


      SendCGINotFoundResponse(self._outfile)
      return
    self._SendSuccessResponse(directory)

  def HandleDiscoveryRequest(self, path):
    """Returns the result of a discovery service request.

    Args:
      path: the SPI API path

    Returns:
      JSON string with result of discovery service API request.
    """
    if path == self._GET_REST_API:
      self._GetRest()
    elif path == self._GET_RPC_API:
      self._GetRpc()
    elif path == self._LIST_API:
      self._List()
    else:
      return False
    return True


class ApiConfigManager(object):
  """Manages loading api configs and method lookup."""

  def __init__(self):
    self._rpc_method_dict = {}
    self._rest_methods = []
    self.configs = {}

  @staticmethod
  def HasSpiEndpoint(config):
    """Checks if an SPI is registered with this App.

    Args:
      config: Parsed app.yaml as an appinfo proto.

    Returns:
      True if any handler is registered for (/_ah/spi/.*).
    """
    return any(h.url.startswith('/_ah/spi/') for h in config.handlers)

  def _AddDiscoveryConfig(self):
    lookup_key = (DiscoveryService.API_CONFIG['name'],
                  DiscoveryService.API_CONFIG['version'])
    self.configs[lookup_key] = DiscoveryService.API_CONFIG

  def ParseApiConfigResponse(self, body):
    """Parses a json api config and registers methods for dispatch.

    Side effects:
      Parses method name, etc for all methods and updates the indexing
      datastructures with the information.

    Args:
      body: body of getApiConfigs response
    """


    try:
      response_obj = json.loads(body)
    except ValueError, unused_err:
      logging.error('Cannot parse BackendService.getApiConfigs response: %s',
                    body)
    else:
      self._AddDiscoveryConfig()
      for api_config_json in response_obj.get('items', []):
        try:
          config = json.loads(api_config_json)
        except ValueError, unused_err:
          logging.error('Can not parse API config: %s',
                        api_config_json)
        else:
          lookup_key = config.get('name', ''), config.get('version', '')
          self.configs[lookup_key] = config

      for config in self.configs.itervalues():
        version = config.get('version', '')





        sorted_methods = self._GetSortedMethods(config.get('methods', {}))

        for method_name, method in sorted_methods:
          self.SaveRpcMethod(method_name, version, method)
          self.SaveRestMethod(method_name, version, method)

  def _GetSortedMethods(self, methods):
    """Get a copy of 'methods' sorted the same way AppEngine sorts them.

    Args:
      methods: Json configuration of an API's methods.

    Returns:
      The same configuration with the methods sorted based on what order
      they'll be checked by the server.
    """
    if not methods:
      return methods


    def _SortMethodsComparison(method_info1, method_info2):
      """Sort method info by path and http_method.

      Args:
        method_info1: Method name and info for the first method to compare.
        method_info2: Method name and info for the method to compare to.

      Returns:
        Negative if the first method should come first, positive if the
        first method should come after the second.  Zero if they're
        equivalent.
      """

      def _ScorePath(path):
        """Calculate the score for this path, used for comparisons.

        Higher scores have priority, and if scores are equal, the path text
        is sorted alphabetically.  Scores are based on the number and location
        of the constant parts of the path.  The server has some special handling
        for variables with regexes, which we don't handle here.

        Args:
          path: The request path that we're calculating a score for.

        Returns:
          The score for the given path.
        """





        score = 0
        parts = path.split('/')
        for part in parts:
          score <<= 1
          if not part or part[0] != '{':

            score += 1



        score <<= 31 - len(parts)
        return score


      path_score1 = _ScorePath(method_info1[1].get('path', ''))
      path_score2 = _ScorePath(method_info2[1].get('path', ''))
      if path_score1 != path_score2:
        return path_score2 - path_score1


      path_result = cmp(method_info1[1].get('path', ''),
                        method_info2[1].get('path', ''))
      if path_result != 0:
        return path_result


      method_result = cmp(method_info1[1].get('httpMethod', ''),
                          method_info2[1].get('httpMethod', ''))
      return method_result

    return sorted(methods.items(), _SortMethodsComparison)

  @staticmethod
  def _ToSafePathParamName(matched_parameter):
    """Creates a safe string to be used as a regex group name.

    Only alphanumeric characters and underscore are allowed in variable name
    tokens, and numeric are not allowed as the first character.

    We cast the matched_parameter to base32 (since the alphabet is safe),
    strip the padding (= not safe) and prepend with _, since we know a token
    can begin with underscore.

    Args:
      matched_parameter: String; parameter matched from URL template.

    Returns:
      String, safe to be used as a regex group name.
    """
    return '_' + base64.b32encode(matched_parameter).rstrip('=')

  @staticmethod
  def _FromSafePathParamName(safe_parameter):
    """Takes a safe regex group name and converts it back to the original value.

    Only alphanumeric characters and underscore are allowed in variable name
    tokens, and numeric are not allowed as the first character.

    The safe_parameter is a base32 representation of the actual value.

    Args:
      safe_parameter: String, safe regex group name.

    Returns:
      String; parameter matched from URL template.
    """
    assert safe_parameter.startswith('_')
    safe_parameter_as_base32 = safe_parameter[1:]

    padding_length = - len(safe_parameter_as_base32) % 8
    padding = '=' * padding_length
    return base64.b32decode(safe_parameter_as_base32 + padding)

  @staticmethod
  def CompilePathPattern(pattern):
    """Generates a compiled regex pattern for a path pattern.

    e.g. '/{!name}/{!version}/notes/{id}'
    returns re.compile(r'/([^:/?#\[\]{}]*)'
                       r'/([^:/?#\[\]{}]*)'
                       r'/notes/(?P<id>[^:/?#\[\]{}]*)')
    Note in this example that !name and !version are reserved variable names
    used to match the API name and version that should not be migrated into the
    method argument namespace.  As such they are not named in the regex, so
    groupdict() excludes them.

    Args:
      pattern: parameterized path pattern to be checked

    Returns:
      compiled regex to match this path pattern
    """

    def ReplaceReservedVariable(match):
      """Replaces a {!variable} with a regex to match it not by name.

      Args:
        match: The matching regex group as sent by re.sub()

      Returns:
        Regex to match the variable by name, if the full pattern was matched.
      """
      if match.lastindex > 1:
        return '%s(%s)' % (match.group(1), _PATH_VALUE_PATTERN)
      return match.group(0)

    def ReplaceVariable(match):
      """Replaces a {variable} with a regex to match it by name.

      Changes the string corresponding to the variable name to the base32
      representation of the string, prepended by an underscore. This is
      necessary because we can have message variable names in URL patterns
      (e.g. via {x.y}) but the character '.' can't be in a regex group name.

      Args:
        match: The matching regex group as sent by re.sub()

      Returns:
        Regex to match the variable by name, if the full pattern was matched.
      """
      if match.lastindex > 1:
        var_name = ApiConfigManager._ToSafePathParamName(match.group(2))
        return '%s(?P<%s>%s)' % (match.group(1), var_name,
                                 _PATH_VALUE_PATTERN)
      return match.group(0)




    pattern = re.sub('(/|^){(%s)}(?=/|$)' % _RESERVED_PATH_VARIABLE_PATTERN,
                     ReplaceReservedVariable, pattern, 2)
    pattern = re.sub('(/|^){(%s)}(?=/|$)' % _PATH_VARIABLE_PATTERN,
                     ReplaceVariable, pattern)
    return re.compile(pattern + '/?$')

  def SaveRpcMethod(self, method_name, version, method):
    """Store JsonRpc api methods in a map for lookup at call time.

    (rpcMethodName, apiVersion) => method.

    Args:
      method_name: Name of the API method
      version: Version of the API
      method: method descriptor (as in the api config file).
    """
    self._rpc_method_dict[(method_name, version)] = method

  def LookupRpcMethod(self, method_name, version):
    """Lookup the JsonRPC method at call time.

    The method is looked up in self._rpc_method_dict, the dictionary that
    it is saved in for SaveRpcMethod().

    Args:
      method_name: String name of the method
      version: String version of the API

    Returns:
      Method descriptor as specified in the API configuration.
    """
    method = self._rpc_method_dict.get((method_name, version))
    return method

  def SaveRestMethod(self, method_name, version, method):
    """Store Rest api methods in a list for lookup at call time.

    The list is self._rest_methods, a list of tuples:
      [(<compiled_path>, <path_pattern>, <method_dict>), ...]
    where:
      <compiled_path> is a compiled regex to match against the incoming URL
      <path_pattern> is a string representing the original path pattern,
        checked on insertion to prevent duplicates.     -and-
      <method_dict> is a dict (httpMethod, apiVersion) => (method_name, method)

    This structure is a bit complex, it supports use in two contexts:
      Creation time:
        - SaveRestMethod is called repeatedly, each method will have a path,
          which we want to be compiled for fast lookup at call time
        - We want to prevent duplicate incoming path patterns, so store the
          un-compiled path, not counting on a compiled regex being a stable
          comparison as it is not documented as being stable for this use.
        - Need to store the method that will be mapped at calltime.
        - Different methods may have the same path but different http method.
          and/or API versions.
      Call time:
        - Quickly scan through the list attempting .match(path) on each
          compiled regex to find the path that matches.
        - When a path is matched, look up the API version and method from the
          request and get the method name and method config for the matching
          API method and method name.

    Args:
      method_name: Name of the API method
      version: Version of the API
      method: method descriptor (as in the api config file).
    """
    path_pattern = _API_REST_PATH_FORMAT % method.get('path', '')
    http_method = method.get('httpMethod', '').lower()
    for _, path, methods in self._rest_methods:
      if path == path_pattern:
        methods[(http_method, version)] = method_name, method
        break
    else:
      self._rest_methods.append(
          (self.CompilePathPattern(path_pattern),
           path_pattern,
           {(http_method, version): (method_name, method)}))

  @staticmethod
  def _GetPathParams(match):
    """Gets path parameters from a regular expression match.

    Args:
      match: _sre.SRE_Match object for a path.

    Returns:
      A dictionary containing the variable names converted from base64
    """
    result = {}
    for var_name, value in match.groupdict().iteritems():
      actual_var_name = ApiConfigManager._FromSafePathParamName(var_name)
      result[actual_var_name] = value
    return result

  def LookupRestMethod(self, path, http_method):
    """Look up the rest method at call time.

    The method is looked up in self._rest_methods, the list it is saved
    in for SaveRestMethod.

    Args:
      path: Path from the URL of the request.
      http_method: HTTP method of the request.

    Returns:
      Tuple of (<method name>, <method>, <params>)
      Where:
        <method name> is the string name of the method that was matched.
        <method> is the descriptor as specified in the API configuration. -and-
        <params> is a dict of path parameters matched in the rest request.
    """
    for compiled_path_pattern, unused_path, methods in self._rest_methods:
      match = compiled_path_pattern.match(path)
      if match:
        params = self._GetPathParams(match)
        version = match.group(2)
        method_key = (http_method.lower(), version)
        method_name, method = methods.get(method_key, (None, None))
        if method is not None:
          break
    else:
      logging.warn('No endpoint found for path: %s', path)
      method_name = None
      method = None
      params = None
    return method_name, method, params


def CreateApiserverDispatcher(config_manager=None):
  """Function to create Apiserver dispatcher.

  Args:
    config_manager: Allow setting of ApiConfigManager for testing.

  Returns:
    New dispatcher capable of handling requests to the built-in apiserver
    handlers.
  """



  from google.appengine.tools import old_dev_appserver

  class ApiserverDispatcher(old_dev_appserver.URLDispatcher):
    """Dispatcher that handles requests to the built-in apiserver handlers."""

    _API_EXPLORER_URL = 'http://apis-explorer.appspot.com/apis-explorer/?base='

    class RequestState(object):
      """Enum tracking request state."""
      INIT = 0
      GET_API_CONFIGS = 1
      SPI_CALL = 2
      END = 3



    def __init__(self, config_manager=None, *args, **kwargs):
      self._is_rpc = None
      self.request = None
      self._request_stage = self.RequestState.INIT
      self._is_batch = False
      if config_manager is None:
        config_manager = ApiConfigManager()
      self.config_manager = config_manager
      self._dispatchers = []
      self._AddDispatcher('/_ah/api/explorer/?$',
                          self.HandleApiExplorerRequest)
      self._AddDispatcher('/_ah/api/static/.*$',
                          self.HandleApiStaticRequest)
      old_dev_appserver.URLDispatcher.__init__(self, *args, **kwargs)

    def _AddDispatcher(self, path_regex, dispatch_function):
      """Add a request path and dispatch handler.

      Args:
        path_regex: Regex path to match against incoming requests.
        dispatch_function: Function to call for these requests.  The function
          should take (request, outfile, base_env_dict) as arguments and
          return True.
      """
      self._dispatchers.append((re.compile(path_regex), dispatch_function))

    def _EndRequest(self):
      """End the request and clean up.

      Sets the request state to END and cleans up any variables that
      need it.
      """
      self._request_stage = self.RequestState.END
      self._is_batch = False

    def IsRpc(self):
      """Check if the current request is an RPC request.

      This should only be used after Dispatch, where this info is cached.

      Returns:
        True if the current request is an RPC.  False if not.
      """
      assert self._is_rpc is not None
      return self._is_rpc

    def DispatchNonApiRequests(self, request, outfile, base_env_dict):
      """Dispatch this request if this is a request to a reserved URL.

      Args:
        request: AppServerRequest.
        outfile: The response file.
        base_env_dict: Dictionary of CGI environment parameters if available.
          Defaults to None.

      Returns:
        False if the request doesn't match one of the reserved URLs this
        handles.  True if it is handled.
      """
      for path_regex, dispatch_function in self._dispatchers:
        if path_regex.match(request.relative_url):
          return dispatch_function(request, outfile, base_env_dict)
      return False

    def Dispatch(self,
                 request,
                 outfile,
                 base_env_dict=None):
      """Handles dispatch to apiserver handlers.

      base_env_dict should contain at least:
      REQUEST_METHOD, REMOTE_ADDR, SERVER_SOFTWARE, SERVER_NAME,
      SERVER_PROTOCOL, SERVER_PORT

      Args:
        request: AppServerRequest.
        outfile: The response file.
        base_env_dict: Dictionary of CGI environment parameters if available.
          Defaults to None.

      Returns:
        AppServerRequest internal redirect for normal API calls or
        None for error conditions (e.g. method not found -> 404) and
        other calls not requiring the GetApiConfigs redirect.
      """
      if self._request_stage != self.RequestState.INIT:
        return self.FailRequest('Dispatch in unexpected state', outfile)

      if not base_env_dict:
        return self.FailRequest('CGI Environment Not Available', outfile)

      if self.DispatchNonApiRequests(request, outfile, base_env_dict):
        return None


      self.request = ApiRequest(base_env_dict, old_dev_appserver, request)





      self._is_rpc = self.request._IsRpc()


      self._request_stage = self.RequestState.GET_API_CONFIGS
      return self.GetApiConfigs(base_env_dict, old_dev_appserver)

    def HandleApiExplorerRequest(self, unused_request, outfile, base_env_dict):
      """Handler for requests to _ah/api/explorer.

      Args:
        unused_request: AppServerRequest.
        outfile: The response file.
        base_env_dict: Dictionary of CGI environment parameters
          if available. Defaults to None.

      Returns:
        True
        We will redirect these requests to the google apis explorer.
      """
      base_url = 'http://%s:%s/_ah/api' % (base_env_dict['SERVER_NAME'],
                                           base_env_dict['SERVER_PORT'])
      redirect_url = self._API_EXPLORER_URL + base_url
      SendCGIRedirectResponse(redirect_url, outfile)
      return True

    def HandleApiStaticRequest(self, request, outfile, unused_base_env_dict):
      """Handler for requests to _ah/api/static/.*.

      Args:
        request: AppServerRequest.
        outfile: The response file.
        unused_base_env_dict: Dictionary of CGI environment parameters
          if available. Defaults to None.

      Returns:
        True
        We will redirect these requests to an endpoint proxy.
      """
      discovery_api_proxy = DiscoveryApiProxy()
      response, body = discovery_api_proxy.GetStaticFile(request.relative_url)
      if response.status == 200:
        SendCGIResponse('200',
                        {'Content-Type': response.getheader('Content-Type')},
                        body, outfile)
      else:
        logging.error('Discovery API proxy failed on %s with %d. Details: %s',
                      request.relative_url, response.status, body)
        SendCGIResponse(response.status, dict(response.getheaders()), body,
                        outfile)
      return True

    def EndRedirect(self, dispatched_output, outfile):
      """Handle the end of getApiConfigs and SPI complete notification.

      This EndRedirect is called twice.

      The first time is upon completion of the BackendService.getApiConfigs()
      call.  After this call, the set of all available methods and their
      parameters / paths / config is contained in dispatched_output.  This is
      parsed and used to dispatch the request to the SPI backend itself.

      In order to cause a second dispatch and EndRedirect, this EndRedirect
      will return an AppServerRequest filled out with the SPI backend request.

      The second time it is called is upon completion of the call to the SPI
      backend. After this call, if the initial request (sent in Dispatch, prior
      to getApiConfigs) is used to reformat the response as needed.  This
      currently only results in changes for JsonRPC requests, where the response
      body is moved into {'result': response_body_goes_here} and the request id
      is copied back into the response.

      Args:
        dispatched_output: resulting output from the SPI
        outfile: final output file for this handler

      Returns:
        An AppServerRequest for redirect or None for an immediate response.
      """
      if self._request_stage == self.RequestState.GET_API_CONFIGS:
        if self.HandleGetApiConfigsResponse(dispatched_output, outfile):
          return self.CallSpi(outfile)
      elif self._request_stage == self.RequestState.SPI_CALL:
        return self.HandleSpiResponse(dispatched_output, outfile)
      else:
        return self.FailRequest('EndRedirect in unexpected state', outfile)

    def GetApiConfigs(self, cgi_env, old_dev_appserver):
      """Makes a call to BackendService.getApiConfigs and parses result.

      Args:
        cgi_env: CGI environment dictionary as passed in by the framework
        old_dev_appserver:
            old_dev_appserver instance used to generate AppServerRequest.

      Returns:
        AppServerRequest to be returned as an internal redirect to getApiConfigs
      """
      request = ApiRequest(cgi_env, old_dev_appserver)
      request.path = 'BackendService.getApiConfigs'
      request.body = '{}'
      return BuildCGIRequest(cgi_env, request, old_dev_appserver)

    @staticmethod
    def VerifyResponse(response, status_code, content_type=None):
      """Verifies that a response has the expected status and content type.

      Args:
        response: Response to be checked.
        status_code: HTTP status code to be compared with response status.
        content_type: acceptable Content-Type: header value, None allows any.

      Returns:
        True if both status_code and content_type match, else False.
      """
      if response.status_code != status_code:
        return False
      if content_type is None:
        return True
      for header in response.headers:
        if header.lower() == 'content-type':
          return response.headers[header].lower() == content_type
      else:
        return False

    @staticmethod
    def ParseCgiResponse(response):
      """Parses a CGI response, returning a headers dict and body.

      Args:
        response: a CGI response

      Returns:
        tuple of ({header: header_value, ...}, body)
      """
      header_dict = {}
      for header in response.headers.headers:
        header_name, header_value = header.split(':', 1)
        header_dict[header_name.strip()] = header_value.strip()

      if response.body:
        body = response.body.read()
      else:
        body = ''
      return header_dict, body

    def HandleGetApiConfigsResponse(self, dispatched_output, outfile):
      """Parses the result of getApiConfigs, returning True on success.

      Args:
        dispatched_output: Output from the getApiConfigs call handler.
        outfile: CGI output handle, used for error conditions.

      Returns:
        True on success, False on failure
      """
      response = old_dev_appserver.RewriteResponse(dispatched_output)
      if self.VerifyResponse(response, 200, 'application/json'):
        self.config_manager.ParseApiConfigResponse(response.body.read())
        return True
      else:
        self.FailRequest('BackendService.getApiConfigs Error', outfile)
        return False

    def CallSpi(self, outfile):
      """Generate SPI call (from earlier-saved request).

      Side effects:
        self.request is modified from Rest/JsonRPC format to apiserving format.

      Args:
        outfile: File to write out CGI-style response in case of error.

      Returns:
        AppServerRequest for redirect or None to send immediate CGI response.
      """
      if self.IsRpc():
        method_config = self.LookupRpcMethod()
        params = None
      else:
        method_config, params = self.LookupRestMethod()
      if method_config:
        try:
          self.TransformRequest(params, method_config)
          discovery_service = DiscoveryService(self.config_manager,
                                               self.request, outfile)

          if not discovery_service.HandleDiscoveryRequest(self.request.path):
            self._request_stage = self.RequestState.SPI_CALL
            return BuildCGIRequest(self.request.cgi_env, self.request,
                                   old_dev_appserver)
        except RequestRejectionError, rejection_error:
          self._EndRequest()
          return SendCGIRejectedResponse(rejection_error, outfile)
      else:
        self._EndRequest()
        cors_handler = ApiserverDispatcher.__CheckCorsHeaders(self.request)
        return SendCGINotFoundResponse(outfile, cors_handler=cors_handler)

    class __CheckCorsHeaders(object):
      """Track information about CORS headers and our response to them."""

      def __init__(self, request):
        self.allow_cors_request = False
        self.origin = None
        self.cors_request_method = None
        self.cors_request_headers = None

        self.__CheckCorsRequest(request)

      def __CheckCorsRequest(self, request):
        """Check for a CORS request, and see if it gets a CORS response."""

        for orig_header, orig_value in request.headers.iteritems():
          if orig_header.lower() == _CORS_HEADER_ORIGIN:
            self.origin = orig_value
          if orig_header.lower() == _CORS_HEADER_REQUEST_METHOD:
            self.cors_request_method = orig_value
          if orig_header.lower() == _CORS_HEADER_REQUEST_HEADERS:
            self.cors_request_headers = orig_value


        if (self.origin and
            ((self.cors_request_method is None) or
             (self.cors_request_method.upper() in _CORS_ALLOWED_METHODS))):
          self.allow_cors_request = True

      def UpdateHeaders(self, headers):
        """Add CORS headers to the response, if needed."""
        if not self.allow_cors_request:
          return


        headers[_CORS_HEADER_ALLOW_ORIGIN] = self.origin
        headers[_CORS_HEADER_ALLOW_METHODS] = ','.join(
            tuple(_CORS_ALLOWED_METHODS))
        if self.cors_request_headers is not None:
          headers[_CORS_HEADER_ALLOW_HEADERS] = self.cors_request_headers

    def HandleSpiResponse(self, dispatched_output, outfile):
      """Handle SPI response, transforming output as needed.

      Args:
        dispatched_output: Response returned by SPI backend.
        outfile: File-like object to write transformed result.

      Returns:
        None
      """

      response = old_dev_appserver.AppServerResponse(
          response_file=dispatched_output)
      response_headers, body = self.ParseCgiResponse(response)



      headers = {}
      for header, value in response_headers.items():
        if (header.lower() == 'content-type' and
            not value.lower().startswith('application/json')):
          return self.FailRequest('Non-JSON reply: %s' % body, outfile)
        elif header.lower() not in ('content-length', 'content-type'):
          headers[header] = value

      if self.IsRpc():
        body = self.TransformJsonrpcResponse(body)
      self._EndRequest()

      cors_handler = ApiserverDispatcher.__CheckCorsHeaders(self.request)
      return SendCGIResponse(response.status_code, headers, body, outfile,
                             cors_handler=cors_handler)

    def FailRequest(self, message, outfile):
      """Write an immediate failure response to outfile, no redirect.

      Args:
        message: Error message to be displayed to user (plain text).
        outfile: File-like object to write CGI response to.

      Returns:
        None
      """
      self._EndRequest()
      if self.request:
        cors_handler = ApiserverDispatcher.__CheckCorsHeaders(self.request)
      else:
        cors_handler = None
      return SendCGIErrorResponse(message, outfile, cors_handler=cors_handler)

    def LookupRestMethod(self):
      """Looks up and returns rest method for the currently-pending request.

      This method uses self.request as the currently-pending request.

      Returns:
        tuple of (method, parameters)
      """
      method_name, method, params = self.config_manager.LookupRestMethod(
          self.request.path, self.request.http_method)
      self.request.method_name = method_name
      return method, params

    def LookupRpcMethod(self):
      """Looks up and returns RPC method for the currently-pending request.

      This method uses self.request as the currently-pending request.

      Returns:
        RPC method that was found for the current request.
      """
      if not self.request.body_obj:
        return None
      try:
        method_name = self.request.body_obj.get('method', '')
      except AttributeError:




        if len(self.request.body_obj) != 1:
          raise NotImplementedError('Batch requests with more than 1 element '
                                    'not supported in dev_appserver.  Found '
                                    '%d elements.' % len(self.request.body_obj))
        logging.info('Converting batch request to single request.')
        self.request.body_obj = self.request.body_obj[0]
        method_name = self.request.body_obj.get('method', '')
        self._is_batch = True

      version = self.request.body_obj.get('apiVersion', '')
      self.request.method_name = method_name
      return self.config_manager.LookupRpcMethod(method_name, version)

    def TransformRequest(self, params, method_config):
      """Transforms self.request to apiserving request.

      This method uses self.request to determine the currently-pending request.
      This method accepts a rest-style or RPC-style request.

      Side effects:
        Updates self.request to apiserving format. (e.g. updating path to be the
        method name, and moving request parameters to the body.)

      Args:
        params: Path parameters dictionary for rest request
        method_config: API config of the method to be called
      """
      if self.IsRpc():
        self.TransformJsonrpcRequest()
      else:
        method_params = method_config.get('request', {}).get('parameters', {})
        self.TransformRestRequest(params, method_params)
      self.request.path = method_config.get('rosyMethod', '')

    def _CheckEnum(self, parameter_name, value, field_parameter):
      """Checks if the parameter value is valid if an enum.

      If the parameter is not an enum, does nothing. If it is, verifies that
      its value is valid.

      Args:
        parameter_name: String; The name of the parameter, which is either just
          a variable name or the name with the index appended. For example 'var'
          or 'var[2]'.
        value: String or list of Strings; The value(s) to be used as enum(s) for
          the parameter.
        field_parameter: The dictionary containing information specific to the
          field in question. This is retrieved from request.parameters in the
          method config.

      Raises:
        EnumRejectionError: If the given value is not among the accepted
          enum values in the field parameter.
      """
      if 'enum' not in field_parameter:
        return

      enum_values = [enum['backendValue']
                     for enum in field_parameter['enum'].values()
                     if 'backendValue' in enum]
      if value not in enum_values:
        raise EnumRejectionError(parameter_name, value, enum_values)

    def _CheckParameter(self, parameter_name, value, field_parameter):
      """Checks if the parameter value is valid against all parameter rules.

      First checks if the value is a list and recursively calls _CheckParameter
      on the values in the list. Otherwise, checks all parameter rules for the
      the current value.

      In the list case, '[index-of-value]' is appended to the parameter name for
      error reporting purposes.

      Currently only checks if value adheres to enum rule, but more can be
      added.

      Args:
        parameter_name: String; The name of the parameter, which is either just
          a variable name or the name with the index appended in the recursive
          case. For example 'var' or 'var[2]'.
        value: String or List of values; The value(s) to be used for the
          parameter.
        field_parameter: The dictionary containing information specific to the
          field in question. This is retrieved from request.parameters in the
          method config.
      """
      if isinstance(value, list):
        for index, element in enumerate(value):
          parameter_name_index = '%s[%d]' % (parameter_name, index)
          self._CheckParameter(parameter_name_index, element, field_parameter)
        return

      self._CheckEnum(parameter_name, value, field_parameter)

    def _AddMessageField(self, field_name, value, params):
      """Converts a . delimitied field name to a message field in parameters.

      For example:
        {'a.b.c': ['foo']}
      becomes:
        {'a': {'b': {'c': ['foo']}}}

      Args:
        field_name: String; the . delimitied name to be converted into a
          dictionary.
        value: The value to be set.
        params: The dictionary holding all the parameters, where the value is
          eventually set.
      """
      if '.' not in field_name:
        params[field_name] = value
        return

      root, remaining = field_name.split('.', 1)
      sub_params = params.setdefault(root, {})
      self._AddMessageField(remaining, value, sub_params)

    def _UpdateFromBody(self, destination, source):
      """Updates the dictionary for an API payload with the request body.

      The values from the body should override those already in the payload, but
      for nested fields (message objects), the values can be combined
      recursively.

      Args:
        destination: A dictionary containing an API payload parsed from the
          path and query parameters in a request.
        source: The object parsed from the body of the request.
      """
      for key, value in source.iteritems():
        destination_value = destination.get(key)
        if isinstance(value, dict) and isinstance(destination_value, dict):
          self._UpdateFromBody(destination_value, value)
        else:
          destination[key] = value

    def TransformRestRequest(self, params, method_parameters):
      """Translates a Rest request/response into an apiserving request/response.

      The request can receive values from the path, query and body and combine
      them before sending them along to the SPI server. In cases of collision,
      objects from the body take precedence over those from the query, which in
      turn take precedence over those from the path.

      In the case that a repeated value occurs in both the query and the path,
      those values can be combined, but if that value also occurred in the body,
      it would override any other values.

      In the case of nested values from message fields, non-colliding values
      from subfields can be combined. For example, if '?a.c=10' occurs in the
      query string and "{'a': {'b': 11}}" occurs in the body, then they will be
      combined as

      {
        'a': {
          'b': 11,
          'c': 10,
        }
      }

      before being sent to the SPI server.

      Side effects:
        Updates self.request to apiserving format. (e.g. updating path to be the
        method name, and moving request parameters to the body.)

      Args:
        params: URL path parameter dict extracted by config_manager lookup.
        method_parameters: Dictionary; The parameters for the request from the
          API config of the method.
      """
      body_obj = {}

      for key, value in params.iteritems():


        body_obj[key] = [value]

      if self.request.parameters:

        for key, value in self.request.parameters.iteritems():
          if key in body_obj:
            body_obj[key] = value + body_obj[key]
          else:
            body_obj[key] = value



      for key, value in body_obj.items():
        current_parameter = method_parameters.get(key, {})
        repeated = current_parameter.get('repeated', False)

        if not repeated:
          body_obj[key] = body_obj[key][0]







        self._CheckParameter(key, body_obj[key], current_parameter)

        message_value = body_obj.pop(key)
        self._AddMessageField(key, message_value, body_obj)

      if self.request.body_obj:
        self._UpdateFromBody(body_obj, self.request.body_obj)

      self.request.body_obj = body_obj
      self.request.body = json.dumps(body_obj)

    def TransformJsonrpcRequest(self):
      """Translates a JsonRpc request/response into apiserving request/response.

      Side effects:
        Updates self.request to apiserving format. (e.g. updating path to be the
        method name, and moving request parameters to the body.)
      """
      body_obj = json.loads(self.request.body) if self.request.body else {}
      try:
        self.request.request_id = body_obj.get('id')
      except AttributeError:




        assert self._is_batch
        if len(body_obj) != 1:
          raise NotImplementedError('Batch requests with more than 1 element '
                                    'not supported in dev_appserver.  Found '
                                    '%d elements.' % len(self.request.body_obj))
        body_obj = body_obj[0]
        self.request.request_id = body_obj.get('id')
      body_obj = body_obj.get('params', {})
      self.request.body = json.dumps(body_obj)

    def TransformJsonrpcResponse(self, response_body):
      """Translates a apiserving response to a JsonRpc response.

      Side effects:
        Updates self.request to JsonRpc format. (e.g. restoring request id
        and moving body object into {'result': body_obj}

      Args:
        response_body: Backend response to transform back to JsonRPC

      Returns:
        Updated, JsonRPC-formatted request body
      """
      body_obj = {'result': json.loads(response_body)}
      if self.request.request_id is not None:
        body_obj['id'] = self.request.request_id
      if self._is_batch:
        body_obj = [body_obj]
      return json.dumps(body_obj)

  return ApiserverDispatcher(config_manager)


def BuildCGIRequest(base_env_dict, request, old_dev_appserver):
  """Build a CGI request to Call a method on an SPI backend.

  Args:
    base_env_dict: CGI environment dict
    request: ApiRequest to be converted to a CGI request
    old_dev_appserver: Handle to old_dev_appserver to generate CGI request.

  Returns:
    old_dev_appserver.AppServerRequest internal redirect object
  """
  if request.headers is None:
    request.headers = {}


  request.headers['Content-Type'] = 'application/json'
  url = SPI_ROOT_FORMAT % (request.port, request.path)
  base_env_dict['REQUEST_METHOD'] = 'POST'






  header_outfile = cStringIO.StringIO()
  body_outfile = cStringIO.StringIO()
  WriteHeaders(request.headers, header_outfile, len(request.body))
  body_outfile.write(request.body)
  header_outfile.seek(0)
  body_outfile.seek(0)
  return old_dev_appserver.AppServerRequest(
      url, None, mimetools.Message(header_outfile), body_outfile)


def WriteHeaders(headers, outfile, content_len=None):
  """Write headers to the output file, updating content length if needed.

  Args:
    headers: Header dict to be written
    outfile: File-like object to send headers to
    content_len: Optional updated content length to update content-length with
  """
  wrote_content_length = False
  for header, value in headers.iteritems():
    if header.lower() == 'content-length' and content_len is not None:
      value = content_len
      wrote_content_length = True
    outfile.write('%s: %s\r\n' % (header, value))
  if not wrote_content_length and content_len:
    outfile.write('Content-Length: %s\r\n' % content_len)


def SendCGINotFoundResponse(outfile, cors_handler=None):
  SendCGIResponse('404', {'Content-Type': 'text/plain'}, 'Not Found', outfile,
                  cors_handler=cors_handler)


def SendCGIErrorResponse(message, outfile, cors_handler=None):
  body = json.dumps({'error': {'message': message}})
  SendCGIResponse('500', {'Content-Type': 'application/json'}, body, outfile,
                  cors_handler=cors_handler)


def SendCGIRejectedResponse(rejection_error, outfile, cors_handler=None):
  body = rejection_error.ToJson()
  SendCGIResponse('400', {'Content-Type': 'application/json'}, body, outfile,
                  cors_handler=cors_handler)


def SendCGIRedirectResponse(redirect_location, outfile, cors_handler=None):
  SendCGIResponse('302', {'Location': redirect_location}, None, outfile,
                  cors_handler=cors_handler)


def SendCGIResponse(status, headers, content, outfile, cors_handler=None):
  """Dump reformatted response to CGI outfile.

  Args:
    status: HTTP status code to send
    headers: Headers dictionary {header_name: header_value, ...}
    content: Body content to write
    outfile: File-like object where response will be written.
    cors_handler: A handler to process CORS request headers and update the
      headers in the response.  Or this can be None, to bypass CORS checks.

  Returns:
    None
  """
  if cors_handler:
    cors_handler.UpdateHeaders(headers)

  outfile.write('Status: %s\r\n' % status)
  WriteHeaders(headers, outfile, len(content) if content else None)
  outfile.write('\r\n')
  if content:
    outfile.write(content)
  outfile.seek(0)
