#!/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.
#
"""Serves content for "script" handlers using an HTTP runtime.

http_runtime supports two ways to start the runtime instance.

START_PROCESS sends the runtime_config protobuf (serialized and base64 encoded
as not all platforms support binary data over stdin) to the runtime instance
over stdin and requires the runtime instance to send the port it is listening on
over stdout.

START_PROCESS_FILE creates two temporary files and adds the paths of both files
to the runtime instance command line. The first file is written by http_runtime
with the runtime_config proto (serialized); the runtime instance is expected to
delete the file after reading it. The second file is written by the runtime
instance with the port it is listening on (the line must be newline terminated);
http_runtime is expected to delete the file after reading it.

TODO: convert all runtimes to START_PROCESS_FILE.
"""


import base64
import contextlib
import httplib
import logging
import os
import socket
import subprocess
import sys
import time
import threading
import urllib
import wsgiref.headers

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 safe_subprocess
from google.appengine.tools.devappserver2 import tee
from google.appengine.tools.devappserver2 import util

START_PROCESS = -1
START_PROCESS_FILE = -2


def _sleep_between_retries(attempt, max_attempts, sleep_base):
  """Sleep between retry attempts.

  Do an exponential backoff between retry attempts on an operation. The general
  pattern for use is:
    for attempt in range(max_attempts):
      # Try operation, either return or break on success
      _sleep_between_retries(attempt, max_attempts, sleep_base)

  Args:
    attempt: Which attempt just failed (0 based).
    max_attempts: The maximum number of attempts that will be made.
    sleep_base: How long in seconds to sleep between the first and second
      attempt (the time will be doubled between each successive attempt). The
      value may be any numeric type that is convertible to float (complex
      won't work but user types that are sufficiently numeric-like will).
  """
  # Don't sleep after the last attempt as we're about to give up.
  if attempt < (max_attempts - 1):
    time.sleep((2 ** attempt) * sleep_base)


def _remove_retry_sharing_violation(path, max_attempts=10, sleep_base=.125):
  """Removes a file (with retries on Windows for sharing violations).

  Args:
    path: The filesystem path to remove.
    max_attempts: The maximum number of attempts to try to remove the path
      before giving up.
    sleep_base: How long in seconds to sleep between the first and second
      attempt (the time will be doubled between each successive attempt). The
      value may be any numeric type that is convertible to float (complex
      won't work but user types that are sufficiently numeric-like will).

  Raises:
    WindowsError: When an error other than a sharing violation occurs.
  """
  if sys.platform == 'win32':
    for attempt in range(max_attempts):
      try:
        os.remove(path)
        break
      except WindowsError as e:
        import winerror
        # Sharing violations are expected to occasionally occur when the runtime
        # instance is context swapped after writing the port but before closing
        # the file. Ignore these and try again.
        if e.winerror != winerror.ERROR_SHARING_VIOLATION:
          raise
      _sleep_between_retries(attempt, max_attempts, sleep_base)
    else:
      logging.warn('Unable to delete %s', path)
  else:
    os.remove(path)


class HttpRuntimeProxy(instance.RuntimeProxy):
  """Manages a runtime subprocess used to handle dynamic content."""

  _VALID_START_PROCESS_FLAVORS = [START_PROCESS, START_PROCESS_FILE]

  def __init__(self, args, runtime_config_getter, module_configuration,
               env=None, start_process_flavor=START_PROCESS):
    """Initializer for HttpRuntimeProxy.

    Args:
      args: Arguments to use to start the runtime subprocess.
      runtime_config_getter: A function that can be called without arguments
          and returns the runtime_config_pb2.Config containing the configuration
          for the runtime.
      module_configuration: An application_configuration.ModuleConfiguration
          instance respresenting the configuration of the module that owns the
          runtime.
      env: A dict of environment variables to pass to the runtime subprocess.
      start_process_flavor: Which version of start process to start your
        runtime process. SUpported flavors are START_PROCESS and
        START_PROCESS_FILE.

    Raises:
      ValueError: An unknown value for start_process_flavor was used.
    """
    super(HttpRuntimeProxy, self).__init__()
    self._host = 'localhost'
    self._port = None
    self._process = None
    self._process_lock = threading.Lock()  # Lock to guard self._process.
    self._prior_error = None
    self._stderr_tee = None
    self._runtime_config_getter = runtime_config_getter
    self._args = args
    self._module_configuration = module_configuration
    self._env = env
    if start_process_flavor not in self._VALID_START_PROCESS_FLAVORS:
      raise ValueError('Invalid start_process_flavor.')
    self._start_process_flavor = start_process_flavor

  def _get_error_file(self):
    for error_handler in self._module_configuration.error_handlers or []:
      if not error_handler.error_code or error_handler.error_code == 'default':
        return os.path.join(self._module_configuration.application_root,
                            error_handler.file)
    else:
      return None

  def handle(self, environ, start_response, url_map, match, request_id,
             request_type):
    """Serves this request by forwarding it to the runtime process.

    Args:
      environ: An environ dict for the request as defined in PEP-333.
      start_response: A function with semantics defined in PEP-333.
      url_map: An appinfo.URLMap instance containing the configuration for the
          handler matching this request.
      match: A re.MatchObject containing the result of the matched URL pattern.
      request_id: A unique string id associated with the request.
      request_type: The type of the request. See instance.*_REQUEST module
          constants.

    Yields:
      A sequence of strings containing the body of the HTTP response.
    """
    if self._prior_error:
      yield self._handle_error(self._prior_error, start_response)
      return

    environ[http_runtime_constants.SCRIPT_HEADER] = match.expand(url_map.script)
    if request_type == instance.BACKGROUND_REQUEST:
      environ[http_runtime_constants.REQUEST_TYPE_HEADER] = 'background'
    elif request_type == instance.SHUTDOWN_REQUEST:
      environ[http_runtime_constants.REQUEST_TYPE_HEADER] = 'shutdown'
    elif request_type == instance.INTERACTIVE_REQUEST:
      environ[http_runtime_constants.REQUEST_TYPE_HEADER] = 'interactive'

    for name in http_runtime_constants.ENVIRONS_TO_PROPAGATE:
      if http_runtime_constants.INTERNAL_ENVIRON_PREFIX + name not in environ:
        value = environ.get(name, None)
        if value is not None:
          environ[
              http_runtime_constants.INTERNAL_ENVIRON_PREFIX + name] = value
    headers = util.get_headers_from_environ(environ)
    if environ.get('QUERY_STRING'):
      url = '%s?%s' % (urllib.quote(environ['PATH_INFO']),
                       environ['QUERY_STRING'])
    else:
      url = urllib.quote(environ['PATH_INFO'])
    if 'CONTENT_LENGTH' in environ:
      headers['CONTENT-LENGTH'] = environ['CONTENT_LENGTH']
      data = environ['wsgi.input'].read(int(environ['CONTENT_LENGTH']))
    else:
      data = ''

    cookies = environ.get('HTTP_COOKIE')
    user_email, admin, user_id = login.get_user_info(cookies)
    if user_email:
      nickname, organization = user_email.split('@', 1)
    else:
      nickname = ''
      organization = ''
    headers[http_runtime_constants.REQUEST_ID_HEADER] = request_id
    headers[http_runtime_constants.INTERNAL_HEADER_PREFIX + 'User-Id'] = (
        user_id)
    headers[http_runtime_constants.INTERNAL_HEADER_PREFIX + 'User-Email'] = (
        user_email)
    headers[
        http_runtime_constants.INTERNAL_HEADER_PREFIX + 'User-Is-Admin'] = (
            str(int(admin)))
    headers[
        http_runtime_constants.INTERNAL_HEADER_PREFIX + 'User-Nickname'] = (
            nickname)
    headers[
        http_runtime_constants.INTERNAL_HEADER_PREFIX + 'User-Organization'] = (
            organization)
    headers['X-AppEngine-Country'] = 'ZZ'
    connection = httplib.HTTPConnection(self._host, self._port)
    with contextlib.closing(connection):
      try:
        connection.connect()
        connection.request(environ.get('REQUEST_METHOD', 'GET'),
                           url,
                           data,
                           dict(headers.items()))

        try:
          response = connection.getresponse()
        except httplib.HTTPException as e:
          # The runtime process has written a bad HTTP response. For example,
          # a Go runtime process may have crashed in app-specific code.
          yield self._handle_error(
              'the runtime process gave a bad HTTP response: %s' % e,
              start_response)
          return

        # Ensures that we avoid merging repeat headers into a single header,
        # allowing use of multiple Set-Cookie headers.
        headers = []
        for name in response.msg:
          for value in response.msg.getheaders(name):
            headers.append((name, value))

        response_headers = wsgiref.headers.Headers(headers)

        error_file = self._get_error_file()
        if (error_file and
            http_runtime_constants.ERROR_CODE_HEADER in response_headers):
          try:
            with open(error_file) as f:
              content = f.read()
          except IOError:
            content = 'Failed to load error handler'
            logging.exception('failed to load error file: %s', error_file)
          start_response('500 Internal Server Error',
                         [('Content-Type', 'text/html'),
                          ('Content-Length', str(len(content)))])
          yield content
          return
        del response_headers[http_runtime_constants.ERROR_CODE_HEADER]
        start_response('%s %s' % (response.status, response.reason),
                       response_headers.items())

        # Yield the response body in small blocks.
        while True:
          try:
            block = response.read(512)
            if not block:
              break
            yield block
          except httplib.HTTPException:
            # The runtime process has encountered a problem, but has not
            # necessarily crashed. For example, a Go runtime process' HTTP
            # handler may have panicked in app-specific code (which the http
            # package will recover from, so the process as a whole doesn't
            # crash). At this point, we have already proxied onwards the HTTP
            # header, so we cannot retroactively serve a 500 Internal Server
            # Error. We silently break here; the runtime process has presumably
            # already written to stderr (via the Tee).
            break
      except Exception:
        with self._process_lock:
          if self._process and self._process.poll() is not None:
            # The development server is in a bad state. Log and return an error
            # message.
            self._prior_error = ('the runtime process for the instance running '
                                 'on port %d has unexpectedly quit' % (
                                     self._port))
            yield self._handle_error(self._prior_error, start_response)
          else:
            raise

  def _handle_error(self, message, start_response):
    # Give the runtime process a bit of time to write to stderr.
    time.sleep(0.1)
    buf = self._stderr_tee.get_buf()
    if buf:
      message = message + '\n\n' + buf
    # TODO: change 'text/plain' to 'text/plain; charset=utf-8'
    # throughout devappserver2.
    start_response('500 Internal Server Error',
                   [('Content-Type', 'text/plain'),
                    ('Content-Length', str(len(message)))])
    return message

  def _read_start_process_file(self, max_attempts=10, sleep_base=.125):
    """Read the single line response expected in the start process file.

    The START_PROCESS_FILE flavor uses a file for the runtime instance to
    report back the port it is listening on. We can't rely on EOF semantics
    as that is a race condition when the runtime instance is simultaneously
    writing the file while the devappserver process is reading it; rather we
    rely on the line being terminated with a newline.

    Args:
      max_attempts: The maximum number of attempts to read the line.
      sleep_base: How long in seconds to sleep between the first and second
        attempt (the time will be doubled between each successive attempt). The
        value may be any numeric type that is convertible to float (complex
        won't work but user types that are sufficiently numeric-like will).

    Returns:
      If a full single line (as indicated by a newline terminator) is found, all
      data read up to that point is returned; return an empty string if no
      newline is read before the process exits or the max number of attempts are
      made.
    """
    try:
      for attempt in range(max_attempts):
        # Yes, the final data may already be in the file even though the
        # process exited. That said, since the process should stay alive
        # if it's exited we don't care anyway.
        if self._process.poll() is not None:
          return ''
        # On Mac, if the first read in this process occurs before the data is
        # written, no data will ever be read by this process without the seek.
        self._process.child_out.seek(0)
        line = self._process.child_out.read()
        if '\n' in line:
          return line
        _sleep_between_retries(attempt, max_attempts, sleep_base)
    finally:
      self._process.child_out.close()
    return ''

  def start(self):
    """Starts the runtime process and waits until it is ready to serve."""
    runtime_config = self._runtime_config_getter()
    # TODO: Use a different process group to isolate the child process
    # from signals sent to the parent. Only available in subprocess in
    # Python 2.7.
    assert self._start_process_flavor in self._VALID_START_PROCESS_FLAVORS
    if self._start_process_flavor == START_PROCESS:
      serialized_config = base64.b64encode(runtime_config.SerializeToString())
      with self._process_lock:
        assert not self._process, 'start() can only be called once'
        self._process = safe_subprocess.start_process(
            self._args,
            serialized_config,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            env=self._env,
            cwd=self._module_configuration.application_root)
      line = self._process.stdout.readline()
    elif self._start_process_flavor == START_PROCESS_FILE:
      serialized_config = runtime_config.SerializeToString()
      with self._process_lock:
        assert not self._process, 'start() can only be called once'
        self._process = safe_subprocess.start_process_file(
            args=self._args,
            input_string=serialized_config,
            env=self._env,
            cwd=self._module_configuration.application_root,
            stderr=subprocess.PIPE)
      line = self._read_start_process_file()
      _remove_retry_sharing_violation(self._process.child_out.name)

    # _stderr_tee may be pre-set by unit tests.
    if self._stderr_tee is None:
      self._stderr_tee = tee.Tee(self._process.stderr, sys.stderr)
      self._stderr_tee.start()
    self._prior_error = None
    self._port = None
    try:
      self._port = int(line)
    except ValueError:
      self._prior_error = 'bad runtime process port [%r]' % line
      logging.error(self._prior_error)
    else:
      # Check if the runtime can serve requests.
      if not self._can_connect():
        self._prior_error = 'cannot connect to runtime on port %r' % self._port
        logging.error(self._prior_error)

  def _can_connect(self):
    connection = httplib.HTTPConnection(self._host, self._port)
    with contextlib.closing(connection):
      try:
        connection.connect()
      except socket.error:
        return False
      else:
        return True

  def quit(self):
    """Causes the runtime process to exit."""
    with self._process_lock:
      assert self._process, 'module was not running'
      try:
        self._process.kill()
      except OSError:
        pass
      # Mac leaks file descriptors without call to join. Suspect a race
      # condition where the interpreter is unable to close the subprocess pipe
      # as the thread hasn't returned from the readline call.
      self._stderr_tee.join(5)
      self._process = None
