#
#

# Copyright (C) 2007, 2008, 2010, 2012 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.

"""HTTP server module.

"""

import BaseHTTPServer
import cgi
import logging
import os
import socket
import time
import signal
import asyncore

from ganeti import http
from ganeti import utils
from ganeti import netutils
from ganeti import compat
from ganeti import errors


WEEKDAYNAME = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
MONTHNAME = [None,
             "Jan", "Feb", "Mar", "Apr", "May", "Jun",
             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

# Default error message
DEFAULT_ERROR_CONTENT_TYPE = "text/html"
DEFAULT_ERROR_MESSAGE = """\
<html>
<head>
<title>Error response</title>
</head>
<body>
<h1>Error response</h1>
<p>Error code %(code)d.
<p>Message: %(message)s.
<p>Error code explanation: %(code)s = %(explain)s.
</body>
</html>
"""


def _DateTimeHeader(gmnow=None):
  """Return the current date and time formatted for a message header.

  The time MUST be in the GMT timezone.

  """
  if gmnow is None:
    gmnow = time.gmtime()
  (year, month, day, hh, mm, ss, wd, _, _) = gmnow
  return ("%s, %02d %3s %4d %02d:%02d:%02d GMT" %
          (WEEKDAYNAME[wd], day, MONTHNAME[month], year, hh, mm, ss))


class _HttpServerRequest(object):
  """Data structure for HTTP request on server side.

  """
  def __init__(self, method, path, headers, body):
    # Request attributes
    self.request_method = method
    self.request_path = path
    self.request_headers = headers
    self.request_body = body

    # Response attributes
    self.resp_headers = {}

    # Private data for request handler (useful in combination with
    # authentication)
    self.private = None

  def __repr__(self):
    status = ["%s.%s" % (self.__class__.__module__, self.__class__.__name__),
              self.request_method, self.request_path,
              "headers=%r" % str(self.request_headers),
              "body=%r" % (self.request_body, )]

    return "<%s at %#x>" % (" ".join(status), id(self))


class _HttpServerToClientMessageWriter(http.HttpMessageWriter):
  """Writes an HTTP response to client.

  """
  def __init__(self, sock, request_msg, response_msg, write_timeout):
    """Writes the response to the client.

    @type sock: socket
    @param sock: Target socket
    @type request_msg: http.HttpMessage
    @param request_msg: Request message, required to determine whether
        response may have a message body
    @type response_msg: http.HttpMessage
    @param response_msg: Response message
    @type write_timeout: float
    @param write_timeout: Write timeout for socket

    """
    self._request_msg = request_msg
    self._response_msg = response_msg
    http.HttpMessageWriter.__init__(self, sock, response_msg, write_timeout)

  def HasMessageBody(self):
    """Logic to detect whether response should contain a message body.

    """
    if self._request_msg.start_line:
      request_method = self._request_msg.start_line.method
    else:
      request_method = None

    response_code = self._response_msg.start_line.code

    # RFC2616, section 4.3: "A message-body MUST NOT be included in a request
    # if the specification of the request method (section 5.1.1) does not allow
    # sending an entity-body in requests"
    #
    # RFC2616, section 9.4: "The HEAD method is identical to GET except that
    # the server MUST NOT return a message-body in the response."
    #
    # RFC2616, section 10.2.5: "The 204 response MUST NOT include a
    # message-body [...]"
    #
    # RFC2616, section 10.3.5: "The 304 response MUST NOT contain a
    # message-body, [...]"

    return (http.HttpMessageWriter.HasMessageBody(self) and
            (request_method is not None and
             request_method != http.HTTP_HEAD) and
            response_code >= http.HTTP_OK and
            response_code not in (http.HTTP_NO_CONTENT,
                                  http.HTTP_NOT_MODIFIED))


class _HttpClientToServerMessageReader(http.HttpMessageReader):
  """Reads an HTTP request sent by client.

  """
  # Length limits
  START_LINE_LENGTH_MAX = 8192
  HEADER_LENGTH_MAX = 4096

  def ParseStartLine(self, start_line):
    """Parses the start line sent by client.

    Example: "GET /index.html HTTP/1.1"

    @type start_line: string
    @param start_line: Start line

    """
    # Empty lines are skipped when reading
    assert start_line

    logging.debug("HTTP request: %s", start_line)

    words = start_line.split()

    if len(words) == 3:
      [method, path, version] = words
      if version[:5] != "HTTP/":
        raise http.HttpBadRequest("Bad request version (%r)" % version)

      try:
        base_version_number = version.split("/", 1)[1]
        version_number = base_version_number.split(".")

        # RFC 2145 section 3.1 says there can be only one "." and
        #   - major and minor numbers MUST be treated as
        #      separate integers;
        #   - HTTP/2.4 is a lower version than HTTP/2.13, which in
        #      turn is lower than HTTP/12.3;
        #   - Leading zeros MUST be ignored by recipients.
        if len(version_number) != 2:
          raise http.HttpBadRequest("Bad request version (%r)" % version)

        version_number = (int(version_number[0]), int(version_number[1]))
      except (ValueError, IndexError):
        raise http.HttpBadRequest("Bad request version (%r)" % version)

      if version_number >= (2, 0):
        raise http.HttpVersionNotSupported("Invalid HTTP Version (%s)" %
                                           base_version_number)

    elif len(words) == 2:
      version = http.HTTP_0_9
      [method, path] = words
      if method != http.HTTP_GET:
        raise http.HttpBadRequest("Bad HTTP/0.9 request type (%r)" % method)

    else:
      raise http.HttpBadRequest("Bad request syntax (%r)" % start_line)

    return http.HttpClientToServerStartLine(method, path, version)


def _HandleServerRequestInner(handler, req_msg):
  """Calls the handler function for the current request.

  """
  handler_context = _HttpServerRequest(req_msg.start_line.method,
                                       req_msg.start_line.path,
                                       req_msg.headers,
                                       req_msg.body)

  logging.debug("Handling request %r", handler_context)

  try:
    try:
      # Authentication, etc.
      handler.PreHandleRequest(handler_context)

      # Call actual request handler
      result = handler.HandleRequest(handler_context)
    except (http.HttpException, errors.RapiTestResult,
            KeyboardInterrupt, SystemExit):
      raise
    except Exception, err:
      logging.exception("Caught exception")
      raise http.HttpInternalServerError(message=str(err))
    except:
      logging.exception("Unknown exception")
      raise http.HttpInternalServerError(message="Unknown error")

    if not isinstance(result, basestring):
      raise http.HttpError("Handler function didn't return string type")

    return (http.HTTP_OK, handler_context.resp_headers, result)
  finally:
    # No reason to keep this any longer, even for exceptions
    handler_context.private = None


class HttpResponder(object):
  # The default request version.  This only affects responses up until
  # the point where the request line is parsed, so it mainly decides what
  # the client gets back when sending a malformed request line.
  # Most web servers default to HTTP 0.9, i.e. don't send a status line.
  default_request_version = http.HTTP_0_9

  responses = BaseHTTPServer.BaseHTTPRequestHandler.responses

  def __init__(self, handler):
    """Initializes this class.

    """
    self._handler = handler

  def __call__(self, fn):
    """Handles a request.

    @type fn: callable
    @param fn: Callback for retrieving HTTP request, must return a tuple
      containing request message (L{http.HttpMessage}) and C{None} or the
      message reader (L{_HttpClientToServerMessageReader})

    """
    response_msg = http.HttpMessage()
    response_msg.start_line = \
      http.HttpServerToClientStartLine(version=self.default_request_version,
                                       code=None, reason=None)

    force_close = True

    try:
      (request_msg, req_msg_reader) = fn()

      response_msg.start_line.version = request_msg.start_line.version

      # RFC2616, 14.23: All Internet-based HTTP/1.1 servers MUST respond
      # with a 400 (Bad Request) status code to any HTTP/1.1 request
      # message which lacks a Host header field.
      if (request_msg.start_line.version == http.HTTP_1_1 and
          not (request_msg.headers and
               http.HTTP_HOST in request_msg.headers)):
        raise http.HttpBadRequest(message="Missing Host header")

      (response_msg.start_line.code, response_msg.headers,
       response_msg.body) = \
        _HandleServerRequestInner(self._handler, request_msg)
    except http.HttpException, err:
      self._SetError(self.responses, self._handler, response_msg, err)
    else:
      # Only wait for client to close if we didn't have any exception.
      force_close = False

    return (request_msg, req_msg_reader, force_close,
            self._Finalize(self.responses, response_msg))

  @staticmethod
  def _SetError(responses, handler, response_msg, err):
    """Sets the response code and body from a HttpException.

    @type err: HttpException
    @param err: Exception instance

    """
    try:
      (shortmsg, longmsg) = responses[err.code]
    except KeyError:
      shortmsg = longmsg = "Unknown"

    if err.message:
      message = err.message
    else:
      message = shortmsg

    values = {
      "code": err.code,
      "message": cgi.escape(message),
      "explain": longmsg,
      }

    (content_type, body) = handler.FormatErrorMessage(values)

    headers = {
      http.HTTP_CONTENT_TYPE: content_type,
      }

    if err.headers:
      headers.update(err.headers)

    response_msg.start_line.code = err.code
    response_msg.headers = headers
    response_msg.body = body

  @staticmethod
  def _Finalize(responses, msg):
    assert msg.start_line.reason is None

    if not msg.headers:
      msg.headers = {}

    msg.headers.update({
      # TODO: Keep-alive is not supported
      http.HTTP_CONNECTION: "close",
      http.HTTP_DATE: _DateTimeHeader(),
      http.HTTP_SERVER: http.HTTP_GANETI_VERSION,
      })

    # Get response reason based on code
    try:
      code_desc = responses[msg.start_line.code]
    except KeyError:
      reason = ""
    else:
      (reason, _) = code_desc

    msg.start_line.reason = reason

    return msg


class HttpServerRequestExecutor(object):
  """Implements server side of HTTP.

  This class implements the server side of HTTP. It's based on code of
  Python's BaseHTTPServer, from both version 2.4 and 3k. It does not
  support non-ASCII character encodings. Keep-alive connections are
  not supported.

  """
  # Timeouts in seconds for socket layer
  WRITE_TIMEOUT = 10
  READ_TIMEOUT = 10
  CLOSE_TIMEOUT = 1

  def __init__(self, server, handler, sock, client_addr):
    """Initializes this class.

    """
    responder = HttpResponder(handler)

    # Disable Python's timeout
    sock.settimeout(None)

    # Operate in non-blocking mode
    sock.setblocking(0)

    request_msg_reader = None
    force_close = True

    logging.debug("Connection from %s:%s", client_addr[0], client_addr[1])
    try:
      # Block for closing connection
      try:
        # Do the secret SSL handshake
        if server.using_ssl:
          sock.set_accept_state()
          try:
            http.Handshake(sock, self.WRITE_TIMEOUT)
          except http.HttpSessionHandshakeUnexpectedEOF:
            # Ignore rest
            return

        (request_msg, request_msg_reader, force_close, response_msg) = \
          responder(compat.partial(self._ReadRequest, sock, self.READ_TIMEOUT))
        if response_msg:
          # HttpMessage.start_line can be of different types
          # Instance of 'HttpClientToServerStartLine' has no 'code' member
          # pylint: disable=E1103,E1101
          logging.info("%s:%s %s %s", client_addr[0], client_addr[1],
                       request_msg.start_line, response_msg.start_line.code)
          self._SendResponse(sock, request_msg, response_msg,
                             self.WRITE_TIMEOUT)
      finally:
        http.ShutdownConnection(sock, self.CLOSE_TIMEOUT, self.WRITE_TIMEOUT,
                                request_msg_reader, force_close)

      sock.close()
    finally:
      logging.debug("Disconnected %s:%s", client_addr[0], client_addr[1])

  @staticmethod
  def _ReadRequest(sock, timeout):
    """Reads a request sent by client.

    """
    msg = http.HttpMessage()

    try:
      reader = _HttpClientToServerMessageReader(sock, msg, timeout)
    except http.HttpSocketTimeout:
      raise http.HttpError("Timeout while reading request")
    except socket.error, err:
      raise http.HttpError("Error reading request: %s" % err)

    return (msg, reader)

  @staticmethod
  def _SendResponse(sock, req_msg, msg, timeout):
    """Sends the response to the client.

    """
    try:
      _HttpServerToClientMessageWriter(sock, req_msg, msg, timeout)
    except http.HttpSocketTimeout:
      raise http.HttpError("Timeout while sending response")
    except socket.error, err:
      raise http.HttpError("Error sending response: %s" % err)


class HttpServer(http.HttpBase, asyncore.dispatcher):
  """Generic HTTP server class

  """
  MAX_CHILDREN = 20

  def __init__(self, mainloop, local_address, port, handler,
               ssl_params=None, ssl_verify_peer=False,
               request_executor_class=None):
    """Initializes the HTTP server

    @type mainloop: ganeti.daemon.Mainloop
    @param mainloop: Mainloop used to poll for I/O events
    @type local_address: string
    @param local_address: Local IP address to bind to
    @type port: int
    @param port: TCP port to listen on
    @type ssl_params: HttpSslParams
    @param ssl_params: SSL key and certificate
    @type ssl_verify_peer: bool
    @param ssl_verify_peer: Whether to require client certificate
        and compare it with our certificate
    @type request_executor_class: class
    @param request_executor_class: an class derived from the
        HttpServerRequestExecutor class

    """
    http.HttpBase.__init__(self)
    asyncore.dispatcher.__init__(self)

    if request_executor_class is None:
      self.request_executor = HttpServerRequestExecutor
    else:
      self.request_executor = request_executor_class

    self.mainloop = mainloop
    self.local_address = local_address
    self.port = port
    self.handler = handler
    family = netutils.IPAddress.GetAddressFamily(local_address)
    self.socket = self._CreateSocket(ssl_params, ssl_verify_peer, family)

    # Allow port to be reused
    self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    self._children = []
    self.set_socket(self.socket)
    self.accepting = True
    mainloop.RegisterSignal(self)

  def Start(self):
    self.socket.bind((self.local_address, self.port))
    self.socket.listen(1024)

  def Stop(self):
    self.socket.close()

  def handle_accept(self):
    self._IncomingConnection()

  def OnSignal(self, signum):
    if signum == signal.SIGCHLD:
      self._CollectChildren(True)

  def _CollectChildren(self, quick):
    """Checks whether any child processes are done

    @type quick: bool
    @param quick: Whether to only use non-blocking functions

    """
    if not quick:
      # Don't wait for other processes if it should be a quick check
      while len(self._children) > self.MAX_CHILDREN:
        try:
          # Waiting without a timeout brings us into a potential DoS situation.
          # As soon as too many children run, we'll not respond to new
          # requests. The real solution would be to add a timeout for children
          # and killing them after some time.
          pid, _ = os.waitpid(0, 0)
        except os.error:
          pid = None
        if pid and pid in self._children:
          self._children.remove(pid)

    for child in self._children:
      try:
        pid, _ = os.waitpid(child, os.WNOHANG)
      except os.error:
        pid = None
      if pid and pid in self._children:
        self._children.remove(pid)

  def _IncomingConnection(self):
    """Called for each incoming connection

    """
    # pylint: disable=W0212
    (connection, client_addr) = self.socket.accept()

    self._CollectChildren(False)

    pid = os.fork()
    if pid == 0:
      # Child process
      try:
        # The client shouldn't keep the listening socket open. If the parent
        # process is restarted, it would fail when there's already something
        # listening (in this case its own child from a previous run) on the
        # same port.
        try:
          self.socket.close()
        except socket.error:
          pass
        self.socket = None

        # In case the handler code uses temporary files
        utils.ResetTempfileModule()

        self.request_executor(self, self.handler, connection, client_addr)
      except Exception: # pylint: disable=W0703
        logging.exception("Error while handling request from %s:%s",
                          client_addr[0], client_addr[1])
        os._exit(1)
      os._exit(0)
    else:
      self._children.append(pid)


class HttpServerHandler(object):
  """Base class for handling HTTP server requests.

  Users of this class must subclass it and override the L{HandleRequest}
  function.

  """
  def PreHandleRequest(self, req):
    """Called before handling a request.

    Can be overridden by a subclass.

    """

  def HandleRequest(self, req):
    """Handles a request.

    Must be overridden by subclass.

    """
    raise NotImplementedError()

  @staticmethod
  def FormatErrorMessage(values):
    """Formats the body of an error message.

    @type values: dict
    @param values: dictionary with keys C{code}, C{message} and C{explain}.
    @rtype: tuple; (string, string)
    @return: Content-type and response body

    """
    return (DEFAULT_ERROR_CONTENT_TYPE, DEFAULT_ERROR_MESSAGE % values)
