Exemplo n.º 1
0
    def _get_module_with_soft_routing(self, module_name, version):
        """Uses soft-routing to find the specified module.

    Soft-routing is an attempt to match the production resolution order, which
    is slightly more permissive than the Modules API behavior. Here are the
    rules allowed:
    1. If a module is requested that doesn't exist, use the default module.
    2. If a module is requested that doesn't exist, and there is no default
    module, use any module.

    Args:
      module_name: The name of the module.
      version: The version id.
    Returns:
      Module object.
    Raises:
      request_info.ModuleDoesNotExistError: The module doesn't exist.
      request_info.VersionDoesNotExistError: The version doesn't exist.
    """
        if not module_name or module_name not in self._module_name_to_module:
            if appinfo.DEFAULT_MODULE in self._module_name_to_module:
                module_name = appinfo.DEFAULT_MODULE
            elif self._module_name_to_module:
                # If there is no default module, but there are other modules, take any.
                # This is somewhat of a hack, and can be removed if we ever enforce the
                # existence of a default module.
                module_name = self._module_name_to_module.keys()[0]
            else:
                raise request_info.ModuleDoesNotExistError(module_name)
        if (version is not None and version !=
                self._module_configurations[module_name].major_version):
            raise request_info.VersionDoesNotExistError()
        return self._module_name_to_module[module_name]
Exemplo n.º 2
0
  def _resolve_target(self, hostname, path):
    """Returns the module and instance that should handle this request.

    Args:
      hostname: A string containing the value of the host header in the request
          or None if one was not present.
      path: A string containing the path of the request.

    Returns:
      A tuple (_module, inst) where:
        _module: The module.Module that should handle this request.
        inst: The instance.Instance that should handle this request or None if
            the module's load balancing should decide on the instance.

    Raises:
      request_info.ModuleDoesNotExistError: if hostname is not known.
    """
    if self._port == 80:
      default_address = self.host
    else:
      default_address = '%s:%s' % (self.host, self._port)
    if not hostname or hostname == default_address:
      return self._module_for_request(path), None

    default_address_offset = hostname.find(default_address)
    if default_address_offset > 0:
      prefix = hostname[:default_address_offset - 1]
      if '.' in prefix:
        raise request_info.ModuleDoesNotExistError(prefix)
      return self._get_module_with_soft_routing(prefix, None), None

    else:
      if ':' in hostname:
        port = int(hostname.split(':', 1)[1])
      else:
        port = 80
      try:
        _module, inst = self._port_registry.get(port)
      except KeyError:
        raise request_info.ModuleDoesNotExistError(hostname)
    if not _module:
      _module = self._module_for_request(path)
    return _module, inst
Exemplo n.º 3
0
  def _resolve_target(self, hostname, path):
    """Returns the module and instance that should handle this request.

    Args:
      hostname: A string containing the value of the host header in the request
          or None if one was not present.
      path: A string containing the path of the request.

    Returns:
      A tuple (_module, inst) where:
        _module: The module.Module that should handle this request.
        inst: The instance.Instance that should handle this request or None if
            the module's load balancing should decide on the instance.

    Raises:
      request_info.ModuleDoesNotExistError: if hostname is not known.
    """
    if self._port == 80:
      default_address = self.host
    else:
      default_address = '%s:%s' % (self.host, self._port)
    if not hostname or hostname == default_address:
      return self._module_for_request(path), None





    default_address_offset = hostname.find(default_address)
    if default_address_offset > 0:
      prefix = hostname[:default_address_offset - 1]
      # The prefix should be 'module', but might be 'instance.version.module',
      # 'version.module', or 'instance.module'. These alternatives work in
      # production, but devappserver2 doesn't support running multiple versions
      # of the same module. All we can really do is route to the default
      # version of the specified module.
      if '.' in prefix:
        logging.warning('Ignoring instance/version in %s; multiple versions '
                        'are not supported in devappserver.', prefix)
      module_name = prefix.split('.')[-1]
      return self._get_module_with_soft_routing(module_name, None), None

    else:
      if ':' in hostname:
        port = int(hostname.split(':', 1)[1])
      else:
        port = 80
      try:
        _module, inst = self._port_registry.get(port)
      except KeyError:
        raise request_info.ModuleDoesNotExistError(hostname)
    if not _module:
      _module = self._module_for_request(path)
    return _module, inst
Exemplo n.º 4
0
 def _get_module(self, module_name, version):
   if not module_name or module_name not in self._module_name_to_module:
     if 'default' in self._module_name_to_module:
       module_name = 'default'
     elif self._module_name_to_module:
       # If there is no default module, but there are other modules, take any.
       # This is somewhat of a hack, and can be removed if we ever enforce the
       # existence of a default module.
       module_name = self._module_name_to_module.keys()[0]
     else:
       raise request_info.ModuleDoesNotExistError(module_name)
   elif (version is not None and
         version != self._module_configurations[module_name].major_version):
     raise request_info.VersionDoesNotExistError()
   return self._module_name_to_module[module_name]
Exemplo n.º 5
0
    def get_default_version(self, _module):
        """Returns the default version for a module.

    Args:
      _module: A str containing the name of the module.

    Returns:
      A str containing the default version for the specified module.

    Raises:
      request_info.ModuleDoesNotExistError: The module does not exist.
    """
        if _module in self._module_configurations:
            return self._module_configurations[_module].major_version
        else:
            raise request_info.ModuleDoesNotExistError(_module)
Exemplo n.º 6
0
    def get_module_by_name(self, _module):
        """Returns the module with the given name.

    Args:
      _module: A str containing the name of the module.

    Returns:
      The module.Module with the provided name.

    Raises:
      request_info.ModuleDoesNotExistError: The module does not exist.
    """
        try:
            return self._module_name_to_module[_module]
        except KeyError:
            raise request_info.ModuleDoesNotExistError(_module)
Exemplo n.º 7
0
    def _get_module(self, module_name, version):
        """Attempts to find the specified module.

    Args:
      module_name: The name of the module.
      version: The version id.
    Returns:
      Module object.
    Raises:
      request_info.ModuleDoesNotExistError: The module doesn't exist.
      request_info.VersionDoesNotExistError: The version doesn't exist.
    """
        if not module_name:
            module_name = appinfo.DEFAULT_MODULE
        if module_name not in self._module_name_to_module:
            raise request_info.ModuleDoesNotExistError()
        if (version is not None and version !=
                self._module_configurations[module_name].major_version):
            raise request_info.VersionDoesNotExistError()
        return self._module_name_to_module[module_name]
Exemplo n.º 8
0
  def _resolve_target(self, hostname, path):
    """Returns the module and instance that should handle this request.

    Args:
      hostname: A string containing the value of the host header in the request
          or None if one was not present.
      path: A string containing the path of the request.

    Returns:
      A tuple (_module, inst) where:
        _module: The module.Module that should handle this request.
        inst: The instance.Instance that should handle this request or None if
            the module's load balancing should decide on the instance.

    Raises:
      request_info.ModuleDoesNotExistError: if hostname is not known.
    """
    if self._port == 80:
      default_address = self.host
    else:
      default_address = '%s:%s' % (self.host, self._port)
    if not hostname or hostname == default_address:
      return self._module_for_request(path), None





    default_address_offset = hostname.find(default_address)
    if default_address_offset > 0:
      prefix = hostname[:default_address_offset - 1]
      # The prefix should be 'module', but might be 'instance.version.module',
      # 'version.module', or 'instance.module'. These alternatives work in
      # production, but devappserver2 doesn't support running multiple versions
      # of the same module. All we can really do is route to the default
      # version of the specified module.
      if '.' in prefix:
        logging.warning('Ignoring instance/version in %s; multiple versions '
                        'are not supported in devappserver.', prefix)
      module_name = prefix.split('.')[-1]
      return self._get_module_with_soft_routing(module_name, None), None

    else:
      def get_port(hostname):
        # This will first check to see if hostname is an IPv6 address, then it
        # will fall back on the old-school method of looking for a colon
        # followed by numbers at the end.
        PORT_RE = re.compile(
          r"^\[[0-9a-fA-F:]+\]:(?P<port>[0-9]+)|.*:(?P<port2>[0-9]+)$")
        matched = PORT_RE.match(hostname)
        return matched and int(matched.group("port") or matched.group("port2"))

      _port = get_port(hostname)
      if _port is not None:
        port = _port
      else:
        port = 80
      try:
        _module, inst = self._port_registry.get(port)
      except KeyError:
        raise request_info.ModuleDoesNotExistError(hostname)
    if not _module:
      _module = self._module_for_request(path)
    return _module, inst