files: #!/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.
  #
  
  
  
  
  """An apiproxy stub that calls a remote handler via HTTP.
  
  This allows easy remote access to the App Engine datastore, and potentially any
  of the other App Engine APIs, using the same interface you use when accessing
  the service locally.
  
  An example Python script:
  ---
  from google.appengine.ext import db
  from google.appengine.ext.remote_api import remote_api_stub
  from myapp import models
  import getpass
  
  def auth_func():
    return (raw_input('Username:'), getpass.getpass('Password:'))
  
  remote_api_stub.ConfigureRemoteApi(None, '/_ah/remote_api', auth_func,
                                     'my-app.appspot.com')
  
  # Now you can access the remote datastore just as if your code was running on
  # App Engine!
  
  houses = models.House.all().fetch(100)
  for a_house in q:
    a_house.doors += 1
  db.put(houses)
  ---
  
  A few caveats:
  - Where possible, avoid iterating over queries. Fetching as many results as you
    will need is faster and more efficient. If you don't know how many results
    you need, or you need 'all of them', iterating is fine.
  - Likewise, it's a good idea to put entities in batches. Instead of calling put
    for each individual entity, accumulate them and put them in batches using
    db.put(), if you can.
  - Requests and responses are still limited to 1MB each, so if you have large
    entities or try and fetch or put many of them at once, your requests may fail.
  """
  
  
  
  
  
  
  
  
  
  import google
  import imp
  import os
  import pickle
  import random
  import sys
  import thread
  import threading
  import yaml
  import hashlib
  
  
  if os.environ.get('APPENGINE_RUNTIME') == 'python27':
    from google.appengine.api import apiproxy_rpc
    from google.appengine.api import apiproxy_stub_map
    from google.appengine.datastore import datastore_pb
    from google.appengine.ext.remote_api import remote_api_pb
    from google.appengine.ext.remote_api import remote_api_services
    from google.appengine.runtime import apiproxy_errors
  else:
    from google.appengine.api import apiproxy_rpc
    from google.appengine.api import apiproxy_stub_map
    from google.appengine.datastore import datastore_pb
    from google.appengine.ext.remote_api import remote_api_pb
    from google.appengine.ext.remote_api import remote_api_services
    from google.appengine.runtime import apiproxy_errors
  
  from google.appengine.tools import appengine_rpc
  
  
  _REQUEST_ID_HEADER = 'HTTP_X_APPENGINE_REQUEST_ID'
  
  
  class Error(Exception):
    """Base class for exceptions in this module."""
  
  
  class ConfigurationError(Error):
    """Exception for configuration errors."""
  
  
  class UnknownJavaServerError(Error):
    """Exception for exceptions returned from a Java remote_api handler."""
  
  
  def GetUserAgent():
    """Determines the value of the 'User-agent' header to use for HTTP
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/remote_api/remote_api_stub.py
files: #!/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.
  #
  
  
  
  
  """An apiproxy stub that calls a remote handler via HTTP.
  
  This allows easy remote access to the App Engine datastore, and potentially any
  of the other App Engine APIs, using the same interface you use when accessing
  the service locally.
  
  An example Python script:
  ---
  from google.appengine.ext import db
  from google.appengine.ext.remote_api import remote_api_stub
  from myapp import models
  import getpass
  
  def auth_func():
    return (raw_input('Username:'), getpass.getpass('Password:'))
  
  remote_api_stub.ConfigureRemoteApi(None, '/_ah/remote_api', auth_func,
                                     'my-app.appspot.com')
  
  # Now you can access the remote datastore just as if your code was running on
  # App Engine!
  
  houses = models.House.all().fetch(100)
  for a_house in q:
    a_house.doors += 1
  db.put(houses)
  ---
  
  A few caveats:
  - Where possible, avoid iterating over queries. Fetching as many results as you
    will need is faster and more efficient. If you don't know how many results
    you need, or you need 'all of them', iterating is fine.
  - Likewise, it's a good idea to put entities in batches. Instead of calling put
    for each individual entity, accumulate them and put them in batches using
    db.put(), if you can.
  - Requests and responses are still limited to 1MB each, so if you have large
    entities or try and fetch or put many of them at once, your requests may fail.
  """
  
  
  
  
  
  
  
  
  
  import google
  import imp
  import os
  import pickle
  import random
  import sys
  import thread
  import threading
  import yaml
  import hashlib
  
  
  if os.environ.get('APPENGINE_RUNTIME') == 'python27':
    from google.appengine.api import apiproxy_rpc
    from google.appengine.api import apiproxy_stub_map
    from google.appengine.datastore import datastore_pb
    from google.appengine.ext.remote_api import remote_api_pb
    from google.appengine.ext.remote_api import remote_api_services
    from google.appengine.runtime import apiproxy_errors
  else:
    from google.appengine.api import apiproxy_rpc
    from google.appengine.api import apiproxy_stub_map
    from google.appengine.datastore import datastore_pb
    from google.appengine.ext.remote_api import remote_api_pb
    from google.appengine.ext.remote_api import remote_api_services
    from google.appengine.runtime import apiproxy_errors
  
  from google.appengine.tools import appengine_rpc
  
  
  _REQUEST_ID_HEADER = 'HTTP_X_APPENGINE_REQUEST_ID'
  
  
  class Error(Exception):
    """Base class for exceptions in this module."""
  
  
  class ConfigurationError(Error):
    """Exception for configuration errors."""
  
  
  class UnknownJavaServerError(Error):
    """Exception for exceptions returned from a Java remote_api handler."""
  
  
  def GetUserAgent():
    """Determines the value of the 'User-agent' header to use for HTTP
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/ext/remote_api/remote_api_stub.py
files: #!/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.
  #
  """The main entry point for the new development server."""
  
  
  import argparse
  import errno
  import getpass
  import itertools
  import logging
  import os
  import sys
  import tempfile
  import time
  
  from google.appengine.datastore import datastore_stub_util
  from google.appengine.tools import boolean_action
  from google.appengine.tools.devappserver2.admin import admin_server
  from google.appengine.tools.devappserver2 import api_server
  from google.appengine.tools.devappserver2 import application_configuration
  from google.appengine.tools.devappserver2 import dispatcher
  from google.appengine.tools.devappserver2 import login
  from google.appengine.tools.devappserver2 import runtime_config_pb2
  from google.appengine.tools.devappserver2 import shutdown
  from google.appengine.tools.devappserver2 import update_checker
  from google.appengine.tools.devappserver2 import wsgi_request_info
  
  from appscale.common import appscale_info
  
  # Initialize logging early -- otherwise some library packages may
  # pre-empt our log formatting.  NOTE: the level is provisional; it may
  # be changed in main() based on the --debug flag.
  logging.basicConfig(
      level=logging.INFO,
      format='%(levelname)-8s %(asctime)s %(filename)s:%(lineno)s] %(message)s')
  
  # Valid choices for --log_level and their corresponding constants in
  # runtime_config_pb2.Config.stderr_log_level.
  _LOG_LEVEL_TO_RUNTIME_CONSTANT = {
      'debug': 0,
      'info': 1,
      'warning': 2,
      'error': 3,
      'critical': 4,
  }
  
  # Valid choices for --dev_appserver_log_level and their corresponding Python
  # logging levels
  _LOG_LEVEL_TO_PYTHON_CONSTANT = {
      'debug': logging.DEBUG,
      'info': logging.INFO,
      'warning': logging.WARNING,
      'error': logging.ERROR,
      'critical': logging.CRITICAL,
  }
  
  
  def _generate_storage_paths(app_id):
    """Yield an infinite sequence of possible storage paths."""
    if sys.platform == 'win32':
      # The temp directory is per-user on Windows so there is no reason to add
      # the username to the generated directory name.
      user_format = ''
    else:
      try:
        user_name = getpass.getuser()
      except Exception:  # The possible set of exceptions is not documented.
        user_format = ''
      else:
        user_format = '.%s' % user_name
  
    tempdir = tempfile.gettempdir()
    yield os.path.join(tempdir, 'appengine.%s%s' % (app_id, user_format))
    for i in itertools.count(1):
      yield os.path.join(tempdir, 'appengine.%s%s.%d' % (app_id, user_format, i))
  
  
  def _get_storage_path(path, app_id):
    """Returns a path to the directory where stub data can be stored."""
    _, _, app_id = app_id.replace(':',
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/tools/devappserver2/devappserver2.py
files: #!/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.
  #
  """The main entry point for the new development server."""
  
  
  import argparse
  import errno
  import getpass
  import itertools
  import logging
  import os
  import sys
  import tempfile
  import time
  
  from google.appengine.datastore import datastore_stub_util
  from google.appengine.tools import boolean_action
  from google.appengine.tools.devappserver2.admin import admin_server
  from google.appengine.tools.devappserver2 import api_server
  from google.appengine.tools.devappserver2 import application_configuration
  from google.appengine.tools.devappserver2 import dispatcher
  from google.appengine.tools.devappserver2 import login
  from google.appengine.tools.devappserver2 import runtime_config_pb2
  from google.appengine.tools.devappserver2 import shutdown
  from google.appengine.tools.devappserver2 import update_checker
  from google.appengine.tools.devappserver2 import wsgi_request_info
  
  from appscale.common import appscale_info
  
  # Initialize logging early -- otherwise some library packages may
  # pre-empt our log formatting.  NOTE: the level is provisional; it may
  # be changed in main() based on the --debug flag.
  logging.basicConfig(
      level=logging.INFO,
      format='%(levelname)-8s %(asctime)s %(filename)s:%(lineno)s] %(message)s')
  
  # Valid choices for --log_level and their corresponding constants in
  # runtime_config_pb2.Config.stderr_log_level.
  _LOG_LEVEL_TO_RUNTIME_CONSTANT = {
      'debug': 0,
      'info': 1,
      'warning': 2,
      'error': 3,
      'critical': 4,
  }
  
  # Valid choices for --dev_appserver_log_level and their corresponding Python
  # logging levels
  _LOG_LEVEL_TO_PYTHON_CONSTANT = {
      'debug': logging.DEBUG,
      'info': logging.INFO,
      'warning': logging.WARNING,
      'error': logging.ERROR,
      'critical': logging.CRITICAL,
  }
  
  
  def _generate_storage_paths(app_id):
    """Yield an infinite sequence of possible storage paths."""
    if sys.platform == 'win32':
      # The temp directory is per-user on Windows so there is no reason to add
      # the username to the generated directory name.
      user_format = ''
    else:
      try:
        user_name = getpass.getuser()
      except Exception:  # The possible set of exceptions is not documented.
        user_format = ''
      else:
        user_format = '.%s' % user_name
  
    tempdir = tempfile.gettempdir()
    yield os.path.join(tempdir, 'appengine.%s%s' % (app_id, user_format))
    for i in itertools.count(1):
      yield os.path.join(tempdir, 'appengine.%s%s.%d' % (app_id, user_format, i))
  
  
  def _get_storage_path(path, app_id):
    """Returns a path to the directory where stub data can be stored."""
    _, _, app_id = app_id.replace(':',
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/tools/devappserver2/devappserver2.py
files: #!/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.
  #
  """Manage the lifecycle of modules and dispatch requests to them."""
  
  import collections
  import logging
  import os
  import threading
  import time
  import urlparse
  import wsgiref.headers
  
  from google.appengine.api import request_info
  from google.appengine.tools.devappserver2 import constants
  from google.appengine.tools.devappserver2 import instance
  from google.appengine.tools.devappserver2 import scheduled_executor
  from google.appengine.tools.devappserver2 import module
  from google.appengine.tools.devappserver2 import start_response_utils
  from google.appengine.tools.devappserver2 import thread_executor
  from google.appengine.tools.devappserver2 import wsgi_server
  
  _THREAD_POOL = thread_executor.ThreadExecutor()
  
  ResponseTuple = collections.namedtuple('ResponseTuple',
                                         ['status', 'headers', 'content'])
  
  
  class PortRegistry(object):
    def __init__(self):
      self._ports = {}
      self._ports_lock = threading.RLock()
  
    def add(self, port, _module, inst):
      with self._ports_lock:
        self._ports[port] = (_module, inst)
  
    def get(self, port):
      with self._ports_lock:
        return self._ports[port]
  
  
  class Dispatcher(request_info.Dispatcher):
    """A devappserver2 implementation of request_info.Dispatcher.
  
    In addition to the request_info.Dispatcher interface, it owns modules and
    manages their lifetimes.
    """
  
    def __init__(self,
                 configuration,
                 host,
                 port,
                 auth_domain,
                 runtime_stderr_loglevel,
                 php_executable_path,
                 enable_php_remote_debugging,
                 python_config,
                 cloud_sql_config,
                 module_to_max_instances,
                 use_mtime_file_watcher,
                 automatic_restart,
                 allow_skipped_files,
                 external_api_port=None):
      """Initializer for Dispatcher.
  
      Args:
        configuration: An application_configuration.ApplicationConfiguration
            instance storing the configuration data for the app.
        host: A string containing the host that any HTTP servers should bind to
            e.g. "localhost".
        port: An int specifying the first port where servers should listen.
        auth_domain: A string containing the auth domain to set in the environment
            variables.
        runtime_stderr_loglevel: An int reprenting the minimum logging level at
            which runtime log messages should be written to stderr. See
            devappserver2.py for possible values.
        php_executable_path: A string containing the path to PHP execution e.g.
            "/usr/bin/php-cgi".
        enable_php_remote_debugging: A boolean indicating whether the PHP
            interpreter should be started with XDebug remote debugging enabled.
        python_config: A runtime_config_pb2.PythonConfig instance containing
            Python runtime-specific configuration. If None then defaults are
            used.
        cloud_sql_config: A runtime_config_pb2.CloudSQL instance containing the
            required configuration for local Google Cloud SQL development. If None
            then Cloud SQL will not be available.
        module_to_max_inst
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/tools/devappserver2/dispatcher.py
files: #!/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.
  #
  """Manage the lifecycle of modules and dispatch requests to them."""
  
  import collections
  import logging
  import os
  import threading
  import time
  import urlparse
  import wsgiref.headers
  
  from google.appengine.api import request_info
  from google.appengine.tools.devappserver2 import constants
  from google.appengine.tools.devappserver2 import instance
  from google.appengine.tools.devappserver2 import scheduled_executor
  from google.appengine.tools.devappserver2 import module
  from google.appengine.tools.devappserver2 import start_response_utils
  from google.appengine.tools.devappserver2 import thread_executor
  from google.appengine.tools.devappserver2 import wsgi_server
  
  _THREAD_POOL = thread_executor.ThreadExecutor()
  
  ResponseTuple = collections.namedtuple('ResponseTuple',
                                         ['status', 'headers', 'content'])
  
  
  class PortRegistry(object):
    def __init__(self):
      self._ports = {}
      self._ports_lock = threading.RLock()
  
    def add(self, port, _module, inst):
      with self._ports_lock:
        self._ports[port] = (_module, inst)
  
    def get(self, port):
      with self._ports_lock:
        return self._ports[port]
  
  
  class Dispatcher(request_info.Dispatcher):
    """A devappserver2 implementation of request_info.Dispatcher.
  
    In addition to the request_info.Dispatcher interface, it owns modules and
    manages their lifetimes.
    """
  
    def __init__(self,
                 configuration,
                 host,
                 port,
                 auth_domain,
                 runtime_stderr_loglevel,
                 php_executable_path,
                 enable_php_remote_debugging,
                 python_config,
                 cloud_sql_config,
                 module_to_max_instances,
                 use_mtime_file_watcher,
                 automatic_restart,
                 allow_skipped_files):
      """Initializer for Dispatcher.
  
      Args:
        configuration: An application_configuration.ApplicationConfiguration
            instance storing the configuration data for the app.
        host: A string containing the host that any HTTP servers should bind to
            e.g. "localhost".
        port: An int specifying the first port where servers should listen.
        auth_domain: A string containing the auth domain to set in the environment
            variables.
        runtime_stderr_loglevel: An int reprenting the minimum logging level at
            which runtime log messages should be written to stderr. See
            devappserver2.py for possible values.
        php_executable_path: A string containing the path to PHP execution e.g.
            "/usr/bin/php-cgi".
        enable_php_remote_debugging: A boolean indicating whether the PHP
            interpreter should be started with XDebug remote debugging enabled.
        python_config: A runtime_config_pb2.PythonConfig instance containing
            Python runtime-specific configuration. If None then defaults are
            used.
        cloud_sql_config: A runtime_config_pb2.CloudSQL instance containing the
            required configuration for local Google Cloud SQL development. If None
            then Cloud SQL will not be available.
        module_to_max_instances: A mapping between a
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/tools/devappserver2/dispatcher.py
files: #!/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.
  #
  """Manage the lifecycle of runtime processes and dispatch requests to them."""
  
  
  import collections
  import cStringIO
  import functools
  import httplib
  import logging
  import math
  import os
  import os.path
  import random
  import re
  import string
  import struct
  import threading
  import time
  import urllib
  import urlparse
  import wsgiref.headers
  
  from google.appengine.api import api_base_pb
  from google.appengine.api import apiproxy_stub_map
  from google.appengine.api import appinfo
  from google.appengine.api import request_info
  from google.appengine.api.logservice import log_service_pb
  from google.appengine.tools.devappserver2 import application_configuration
  from google.appengine.tools.devappserver2 import blob_image
  from google.appengine.tools.devappserver2 import blob_upload
  from google.appengine.tools.devappserver2 import channel
  from google.appengine.tools.devappserver2 import constants
  
  from google.appengine.tools.devappserver2 import endpoints
  from google.appengine.tools.devappserver2 import errors
  from google.appengine.tools.devappserver2 import file_watcher
  from google.appengine.tools.devappserver2 import go_runtime
  from google.appengine.tools.devappserver2 import http_runtime_constants
  from google.appengine.tools.devappserver2 import instance
  from google.appengine.tools.devappserver2 import login
  from google.appengine.tools.devappserver2 import php_runtime
  from google.appengine.tools.devappserver2 import python_runtime
  from google.appengine.tools.devappserver2 import request_rewriter
  from google.appengine.tools.devappserver2 import runtime_config_pb2
  from google.appengine.tools.devappserver2 import start_response_utils
  from google.appengine.tools.devappserver2 import static_files_handler
  from google.appengine.tools.devappserver2 import thread_executor
  from google.appengine.tools.devappserver2 import url_handler
  from google.appengine.tools.devappserver2 import util
  from google.appengine.tools.devappserver2 import wsgi_handler
  from google.appengine.tools.devappserver2 import wsgi_server
  
  
  _LOWER_HEX_DIGITS = string.hexdigits.lower()
  _UPPER_HEX_DIGITS = string.hexdigits.upper()
  _REQUEST_ID_HASH_LENGTH = 8
  
  _THREAD_POOL = thread_executor.ThreadExecutor()
  _RESTART_INSTANCES_CONFIG_CHANGES = frozenset(
      [application_configuration.NORMALIZED_LIBRARIES_CHANGED,
       application_configuration.SKIP_FILES_CHANGED,
       application_configuration.NOBUILD_FILES_CHANGED,
       # The server must be restarted when the handlers change because files
       # appearing in static content handlers make them unavailable to the
       # runtime.
       application_configuration.HANDLERS_CHANGED,
       application_configuration.ENV_VARIABLES_CHANGED])
  
  _REQUEST_LOGGING_BLACKLIST_RE = re.compile(
      r'^/_ah/(?:channel
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/tools/devappserver2/module.py
files: #!/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.
  #
  """Manage the lifecycle of runtime processes and dispatch requests to them."""
  
  
  import collections
  import cStringIO
  import functools
  import httplib
  import logging
  import math
  import os
  import os.path
  import random
  import re
  import string
  import threading
  import time
  import urllib
  import urlparse
  import wsgiref.headers
  
  from google.appengine.api import api_base_pb
  from google.appengine.api import apiproxy_stub_map
  from google.appengine.api import appinfo
  from google.appengine.api import request_info
  from google.appengine.api.logservice import log_service_pb
  from google.appengine.tools.devappserver2 import application_configuration
  from google.appengine.tools.devappserver2 import blob_image
  from google.appengine.tools.devappserver2 import blob_upload
  from google.appengine.tools.devappserver2 import channel
  from google.appengine.tools.devappserver2 import constants
  
  from google.appengine.tools.devappserver2 import endpoints
  from google.appengine.tools.devappserver2 import errors
  from google.appengine.tools.devappserver2 import file_watcher
  from google.appengine.tools.devappserver2 import go_runtime
  from google.appengine.tools.devappserver2 import http_runtime_constants
  from google.appengine.tools.devappserver2 import instance
  from google.appengine.tools.devappserver2 import login
  from google.appengine.tools.devappserver2 import php_runtime
  from google.appengine.tools.devappserver2 import python_runtime
  from google.appengine.tools.devappserver2 import request_rewriter
  from google.appengine.tools.devappserver2 import runtime_config_pb2
  from google.appengine.tools.devappserver2 import start_response_utils
  from google.appengine.tools.devappserver2 import static_files_handler
  from google.appengine.tools.devappserver2 import thread_executor
  from google.appengine.tools.devappserver2 import url_handler
  from google.appengine.tools.devappserver2 import util
  from google.appengine.tools.devappserver2 import wsgi_handler
  from google.appengine.tools.devappserver2 import wsgi_server
  
  
  _LOWER_HEX_DIGITS = string.hexdigits.lower()
  _UPPER_HEX_DIGITS = string.hexdigits.upper()
  _REQUEST_ID_HASH_LENGTH = 8
  
  _THREAD_POOL = thread_executor.ThreadExecutor()
  _RESTART_INSTANCES_CONFIG_CHANGES = frozenset(
      [application_configuration.NORMALIZED_LIBRARIES_CHANGED,
       application_configuration.SKIP_FILES_CHANGED,
       application_configuration.NOBUILD_FILES_CHANGED,
       # The server must be restarted when the handlers change because files
       # appearing in static content handlers make them unavailable to the
       # runtime.
       application_configuration.HANDLERS_CHANGED,
       application_configuration.ENV_VARIABLES_CHANGED])
  
  _REQUEST_LOGGING_BLACKLIST_RE = re.compile(
      r'^/_ah/(?:channel/(?:dev
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/tools/devappserver2/module.py
files: #!/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.
  #
  """A Python devappserver2 runtime."""
  
  
  import base64
  import os
  import struct
  import sys
  import time
  import traceback
  
  import google
  
  from google.appengine.api import rdbms_mysqldb
  from google.appengine.ext.remote_api import remote_api_stub
  from google.appengine.tools.devappserver2 import request_rewriter
  from google.appengine.tools.devappserver2 import runtime_config_pb2
  from google.appengine.tools.devappserver2 import wsgi_server
  from google.appengine.tools.devappserver2.python import sandbox
  
  
  _STARTUP_FAILURE_TEMPLATE = """
  <!DOCTYPE html>
  <html>
  <head>
  <title>Startup Script Failure</title>
  </head>
  
  <body>
  <b>Debugger startup failed: {exception_message}</b>
  <details>
    <summary>Configuration</summary>
    <pre><code>{config}</code></pre>
  </details>
  <details>
    <summary>Traceback</summary>
    <pre><code>{traceback}</code></pre>
  </details>
  </body>
  </html>"""
  
  
  def setup_stubs(config, external_api_port=None):
    """Sets up API stubs using remote API."""
    if external_api_port is None:
      external_api_server = None
    else:
      external_api_server = 'localhost:{}'.format(external_api_port)
  
    remote_api_stub.ConfigureRemoteApi(config.app_id, '/', lambda: ('', ''),
                                       'localhost:%d' % config.api_port,
                                       use_remote_datastore=False,
                                       use_async_rpc=True,
                                       external_api_server=external_api_server)
  
    if config.HasField('cloud_sql_config'):
      # Connect the RDBMS API to MySQL.
      sys.modules['google.appengine.api.rdbms'] = rdbms_mysqldb
      google.appengine.api.rdbms = rdbms_mysqldb
  
      connect_kwargs = dict(host=config.cloud_sql_config.mysql_host,
                            port=config.cloud_sql_config.mysql_port,
                            user=config.cloud_sql_config.mysql_user,
                            passwd=config.cloud_sql_config.mysql_password)
  
      if config.cloud_sql_config.mysql_socket:
        connect_kwargs['unix_socket'] = config.cloud_sql_config.mysql_socket
      elif (os.name == 'posix' and
            config.cloud_sql_config.mysql_host == 'localhost'):
        # From http://dev.mysql.com/doc/refman/5.0/en/connecting.html:
        # "On Unix, MySQL programs treat the host name localhost specially,
        # in a way that is likely different from what you expect compared to
        # other network-based programs. For connections to localhost, MySQL
        # programs attempt to connect to the local server by using a Unix socket
        # file. This occurs even if a --port or -P option is given to specify a
        # port number."
        #
        # This logic is duplicated in rdbms_mysqldb.connect but FindUnixSocket
        #
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/tools/devappserver2/python/runtime.py
files: #!/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.
  #
  """A Python devappserver2 runtime."""
  
  
  import base64
  import os
  import sys
  import time
  import traceback
  
  import google
  
  from google.appengine.api import rdbms_mysqldb
  from google.appengine.ext.remote_api import remote_api_stub
  from google.appengine.tools.devappserver2 import request_rewriter
  from google.appengine.tools.devappserver2 import runtime_config_pb2
  from google.appengine.tools.devappserver2 import wsgi_server
  from google.appengine.tools.devappserver2.python import sandbox
  
  
  _STARTUP_FAILURE_TEMPLATE = """
  <!DOCTYPE html>
  <html>
  <head>
  <title>Startup Script Failure</title>
  </head>
  
  <body>
  <b>Debugger startup failed: {exception_message}</b>
  <details>
    <summary>Configuration</summary>
    <pre><code>{config}</code></pre>
  </details>
  <details>
    <summary>Traceback</summary>
    <pre><code>{traceback}</code></pre>
  </details>
  </body>
  </html>"""
  
  
  def setup_stubs(config):
    """Sets up API stubs using remote API."""
    remote_api_stub.ConfigureRemoteApi(config.app_id, '/', lambda: ('', ''),
                                       'localhost:%d' % config.api_port,
                                       use_remote_datastore=False,
                                       use_async_rpc=True)
  
    if config.HasField('cloud_sql_config'):
      # Connect the RDBMS API to MySQL.
      sys.modules['google.appengine.api.rdbms'] = rdbms_mysqldb
      google.appengine.api.rdbms = rdbms_mysqldb
  
      connect_kwargs = dict(host=config.cloud_sql_config.mysql_host,
                            port=config.cloud_sql_config.mysql_port,
                            user=config.cloud_sql_config.mysql_user,
                            passwd=config.cloud_sql_config.mysql_password)
  
      if config.cloud_sql_config.mysql_socket:
        connect_kwargs['unix_socket'] = config.cloud_sql_config.mysql_socket
      elif (os.name == 'posix' and
            config.cloud_sql_config.mysql_host == 'localhost'):
        # From http://dev.mysql.com/doc/refman/5.0/en/connecting.html:
        # "On Unix, MySQL programs treat the host name localhost specially,
        # in a way that is likely different from what you expect compared to
        # other network-based programs. For connections to localhost, MySQL
        # programs attempt to connect to the local server by using a Unix socket
        # file. This occurs even if a --port or -P option is given to specify a
        # port number."
        #
        # This logic is duplicated in rdbms_mysqldb.connect but FindUnixSocket
        # will not worked in devappserver2 when rdbms_mysqldb.connect is called
        # because os.access is replaced in the sandboxed environment.
        #
        # A warning is not logged if FindUnixSocket returns None because
  
  [... the rest is omitted ...]
files: AppServer/google/appengine/tools/devappserver2/python/runtime.py