#!/usr/bin/env python

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.

import BaseHTTPServer
import SimpleHTTPServer
import errno
import logging
import threading
import posixpath
import socket
import sys
import os
import urllib
import urlparse
import re
import moznetwork
import time
from SocketServer import ThreadingMixIn

class EasyServer(ThreadingMixIn, BaseHTTPServer.HTTPServer):
    allow_reuse_address = True
    acceptable_errors = (errno.EPIPE, errno.ECONNABORTED)

    def handle_error(self, request, client_address):
        error = sys.exc_value

        if ((isinstance(error, socket.error) and
             isinstance(error.args, tuple) and
             error.args[0] in self.acceptable_errors)
            or
            (isinstance(error, IOError) and
             error.errno in self.acceptable_errors)):
            pass  # remote hang up before the result is sent
        else:
            logging.error(error)


class Request(object):
    """Details of a request."""

    # attributes from urlsplit that this class also sets
    uri_attrs = ('scheme', 'netloc', 'path', 'query', 'fragment')

    def __init__(self, uri, headers, rfile=None):
        self.uri = uri
        self.headers = headers
        parsed = urlparse.urlsplit(uri)
        for i, attr in enumerate(self.uri_attrs):
            setattr(self, attr, parsed[i])
        try:
            body_len = int(self.headers.get('Content-length', 0))
        except ValueError:
            body_len = 0
        if body_len and rfile:
            self.body = rfile.read(body_len)
        else:
            self.body = None


class RequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):

    docroot = os.getcwd() # current working directory at time of import
    proxy_host_dirs = False
    request_log = []
    log_requests = False
    request = None

    def __init__(self, *args, **kwargs):
        SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, *args, **kwargs)
        self.extensions_map['.svg'] = 'image/svg+xml'

    def _try_handler(self, method):
        if self.log_requests:
            self.request_log.append({ 'method': method,
                                      'path': self.request.path,
                                      'time': time.time() })

        handlers = [handler for handler in self.urlhandlers
                    if handler['method'] == method]
        for handler in handlers:
            m = re.match(handler['path'], self.request.path)
            if m:
                (response_code, headerdict, data) = \
                    handler['function'](self.request, *m.groups())
                self.send_response(response_code)
                for (keyword, value) in headerdict.iteritems():
                    self.send_header(keyword, value)
                self.end_headers()
                self.wfile.write(data)

                return True

        return False

    def _find_path(self):
        """Find the on-disk path to serve this request from,
        using self.path_mappings and self.docroot.
        Return (url_path, disk_path)."""
        path_components = filter(None, self.request.path.split('/'))
        for prefix, disk_path in self.path_mappings.iteritems():
            prefix_components = filter(None, prefix.split('/'))
            if len(path_components) < len(prefix_components):
                continue
            if path_components[:len(prefix_components)] == prefix_components:
                return ('/'.join(path_components[len(prefix_components):]),
                        disk_path)
        if self.docroot:
            return self.request.path, self.docroot
        return None

    def parse_request(self):
        retval = SimpleHTTPServer.SimpleHTTPRequestHandler.parse_request(self)
        self.request = Request(self.path, self.headers, self.rfile)
        return retval

    def do_GET(self):
        if not self._try_handler('GET'):
            res = self._find_path()
            if res:
                self.path, self.disk_root = res
                # don't include query string and fragment, and prepend
                # host directory if required.
                if self.request.netloc and self.proxy_host_dirs:
                    self.path = '/' + self.request.netloc + \
                        self.path
                SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
            else:
                self.send_response(404)
                self.end_headers()
                self.wfile.write('')

    def do_POST(self):
        # if we don't have a match, we always fall through to 404 (this may
        # not be "technically" correct if we have a local file at the same
        # path as the resource but... meh)
        if not self._try_handler('POST'):
            self.send_response(404)
            self.end_headers()
            self.wfile.write('')

    def do_DEL(self):
        # if we don't have a match, we always fall through to 404 (this may
        # not be "technically" correct if we have a local file at the same
        # path as the resource but... meh)
        if not self._try_handler('DEL'):
            self.send_response(404)
            self.end_headers()
            self.wfile.write('')

    def translate_path(self, path):
        # this is taken from SimpleHTTPRequestHandler.translate_path(),
        # except we serve from self.docroot instead of os.getcwd(), and
        # parse_request()/do_GET() have already stripped the query string and
        # fragment and mangled the path for proxying, if required.
        path = posixpath.normpath(urllib.unquote(self.path))
        words = path.split('/')
        words = filter(None, words)
        path = self.disk_root
        for word in words:
            drive, word = os.path.splitdrive(word)
            head, word = os.path.split(word)
            if word in (os.curdir, os.pardir): continue
            path = os.path.join(path, word)
        return path


    # I found on my local network that calls to this were timing out
    # I believe all of these calls are from log_message
    def address_string(self):
        return "a.b.c.d"

    # This produces a LOT of noise
    def log_message(self, format, *args):
        pass


class MozHttpd(object):
    """
    :param host: Host from which to serve (default 127.0.0.1)
    :param port: Port from which to serve (default 8888)
    :param docroot: Server root (default os.getcwd())
    :param urlhandlers: Handlers to specify behavior against method and path match (default None)
    :param path_mappings: A dict mapping URL prefixes to additional on-disk paths.
    :param proxy_host_dirs: Toggle proxy behavior (default False)
    :param log_requests: Toggle logging behavior (default False)

    Very basic HTTP server class. Takes a docroot (path on the filesystem)
    and a set of urlhandler dictionaries of the form:

    ::

      {
        'method': HTTP method (string): GET, POST, or DEL,
        'path': PATH_INFO (regular expression string),
        'function': function of form fn(arg1, arg2, arg3, ..., request)
      }

    and serves HTTP. For each request, MozHttpd will either return a file
    off the docroot, or dispatch to a handler function (if both path and
    method match).

    Note that one of docroot or urlhandlers may be None (in which case no
    local files or handlers, respectively, will be used). If both docroot or
    urlhandlers are None then MozHttpd will default to serving just the local
    directory.

    MozHttpd also handles proxy requests (i.e. with a full URI on the request
    line).  By default files are served from docroot according to the request
    URI's path component, but if proxy_host_dirs is True, files are served
    from <self.docroot>/<host>/.

    For example, the request "GET http://foo.bar/dir/file.html" would
    (assuming no handlers match) serve <docroot>/dir/file.html if
    proxy_host_dirs is False, or <docroot>/foo.bar/dir/file.html if it is
    True.
    """

    def __init__(self,
                 host="127.0.0.1",
                 port=0,
                 docroot=None,
                 urlhandlers=None,
                 path_mappings=None,
                 proxy_host_dirs=False,
                 log_requests=False):
        self.host = host
        self.port = int(port)
        self.docroot = docroot
        if not (urlhandlers or docroot or path_mappings):
            self.docroot = os.getcwd()
        self.proxy_host_dirs = proxy_host_dirs
        self.httpd = None
        self.urlhandlers = urlhandlers or []
        self.path_mappings = path_mappings or {}
        self.log_requests = log_requests
        self.request_log = []

        class RequestHandlerInstance(RequestHandler):
            docroot = self.docroot
            urlhandlers = self.urlhandlers
            path_mappings = self.path_mappings
            proxy_host_dirs = self.proxy_host_dirs
            request_log = self.request_log
            log_requests = self.log_requests

        self.handler_class = RequestHandlerInstance

    def start(self, block=False):
        """
        Starts the server.

        If `block` is True, the call will not return. If `block` is False, the
        server will be started on a separate thread that can be terminated by
        a call to stop().
        """
        self.httpd = EasyServer((self.host, self.port), self.handler_class)
        if block:
            self.httpd.serve_forever()
        else:
            self.server = threading.Thread(target=self.httpd.serve_forever)
            self.server.setDaemon(True) # don't hang on exit
            self.server.start()

    def stop(self):
        """
        Stops the server.

        If the server is not running, this method has no effect.
        """
        if self.httpd:
            ### FIXME: There is no shutdown() method in Python 2.4...
            try:
                self.httpd.shutdown()
            except AttributeError:
                pass
        self.httpd = None

    def get_url(self, path="/"):
        """
        Returns a URL that can be used for accessing the server (e.g. http://192.168.1.3:4321/)

        :param path: Path to append to URL (e.g. if path were /foobar.html you would get a URL like
                     http://192.168.1.3:4321/foobar.html). Default is `/`.
        """
        if not self.httpd:
            return None

        return "http://%s:%s%s" % (self.host, self.httpd.server_port, path)

    __del__ = stop


def main(args=sys.argv[1:]):

    # parse command line options
    from optparse import OptionParser
    parser = OptionParser()
    parser.add_option('-p', '--port', dest='port',
                      type="int", default=8888,
                      help="port to run the server on [DEFAULT: %default]")
    parser.add_option('-H', '--host', dest='host',
                      default='127.0.0.1',
                      help="host [DEFAULT: %default]")
    parser.add_option('-i', '--external-ip', action="store_true",
                      dest='external_ip', default=False,
                      help="find and use external ip for host")
    parser.add_option('-d', '--docroot', dest='docroot',
                      default=os.getcwd(),
                      help="directory to serve files from [DEFAULT: %default]")
    options, args = parser.parse_args(args)
    if args:
        parser.error("mozhttpd does not take any arguments")

    if options.external_ip:
        host = moznetwork.get_lan_ip()
    else:
        host = options.host

    # create the server
    server = MozHttpd(host=host, port=options.port, docroot=options.docroot)

    print "Serving '%s' at %s:%s" % (server.docroot, server.host, server.port)
    server.start(block=True)

if __name__ == '__main__':
    main()
