Example #1
0
def run_simple(
    hostname,
    port,
    application,
    use_reloader=False,
    use_debugger=False,
    use_evalex=True,
    extra_files=None,
    reloader_interval=1,
    reloader_type="auto",
    threaded=False,
    processes=1,
    request_handler=None,
    static_files=None,
    passthrough_errors=False,
    ssl_context=None,
):
    if use_debugger:
        from werkzeug.debug import DebuggedApplication

        application = DebuggedApplication(application, use_evalex)
    if static_files:
        from werkzeug.wsgi import SharedDataMiddleware

        application = SharedDataMiddleware(application, static_files)

    def inner():
        # Override here
        make_server(
            hostname, port, application, threaded, processes, request_handler, passthrough_errors, ssl_context
        ).serve_forever()

    if os.environ.get("WERKZEUG_RUN_MAIN") != "true":
        display_hostname = hostname != "*" and hostname or "localhost"
        if ":" in display_hostname:
            display_hostname = "[%s]" % display_hostname
        quit_msg = "(Press CTRL+C to quit)"
        _log(
            "info",
            " * Running on %s://%s:%d/ %s",
            ssl_context is None and "http" or "https",
            display_hostname,
            port,
            quit_msg,
        )
    if use_reloader:
        # Create and destroy a socket so that any exceptions are raised before
        # we spawn a separate Python interpreter and lose this ability.
        address_family = select_ip_version(hostname, port)
        test_socket = socket.socket(address_family, socket.SOCK_STREAM)
        test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        test_socket.bind((hostname, port))
        test_socket.close()

        from werkzeug._reloader import run_with_reloader

        run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
    else:
        inner()
Example #2
0
    def runServer(self):
        """Starts up the server. It (will) support different config options via the config plugin."""
        config = pm.getService("config")
        debug = config.get("flask.debug")
        cFCGI = config.get("flask.fcgi")
        host = config.get("flask.bind")
        app_port = config.get("flask.app_port")
        fcgi_port = config.get("flask.fcgi_port")
        must_have_client_cert = config.get("flask.force_client_cert")

        if cFCGI:
            logger.info("registering fcgi server at %s:%i", host, fcgi_port)
            from flup.server.fcgi import WSGIServer
            WSGIServer(self._app, bindAddress=(host, fcgi_port)).run()
        else:
            logger.info("registering app server at %s:%i", host, app_port)
            # do the following line manually, so we can intervene and adjust the ssl context
            # self._app.run(host=host, port=app_port, ssl_context='adhoc', debug=debug, request_handler=ClientCertHTTPRequestHandler)
            
            # the code from flask's `run...`
            # see https://github.com/mitsuhiko/flask/blob/master/flask/app.py
            options = {}
            try:
                # now the code from werkzeug's `run_simple(host, app_port, self._app, **options)`
                # see https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/serving.py
                from werkzeug.debug import DebuggedApplication
                import socket
                application = DebuggedApplication(self._app, True)

                # Set up an SSL context
                cert_path = expand_eisoil_path(config.get("delegatetools.trusted_cert_path"))
                cert_key_path = expand_eisoil_path(config.get("delegatetools.trusted_cert_keys_path"))

                context = SSL.Context(SSL.SSLv23_METHOD)
                context_crt = os.path.join(cert_path, "ch-cert.pem")
                context_key = os.path.join(cert_key_path, "ch-key.pem")
                try:
                    context.use_certificate_file(context_crt)
                    context.use_privatekey_file(context_key)
                except Exception as e:
                    logger.critical("error starting flask server. Cert or key is missing under %s", cert_path)
                    sys.exit(e)

                def inner():
                    # server = serving.make_server(host, app_port, self._app, False, 1, ClientCertHTTPRequestHandler, False, 'adhoc')
                    server = serving.make_server(host, app_port, self._app, False, 1, ClientCertHTTPRequestHandler, False, ssl_context=context)
                    # The following line is the reason why I copied all that code!
                    if must_have_client_cert:
                        server.ssl_context.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, lambda a,b,c,d,e: True)
                    # That's it
                    server.serve_forever()
                address_family = serving.select_ip_version(host, app_port)
                test_socket = socket.socket(address_family, socket.SOCK_STREAM)
                test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                test_socket.bind((host, app_port))
                test_socket.close()
                serving.run_with_reloader(inner, None, 1)
            finally:
                self._app._got_first_request = False
Example #3
0
    def runServer(self):
        """Starts up the server. It (will) support different config options via the config plugin."""
        config = pm.getService("config")
        debug = config.get("flask.debug")
        cFCGI = config.get("flask.fcgi")
        host = config.get("flask.bind")
        app_port = config.get("flask.app_port")
        fcgi_port = config.get("flask.fcgi_port")
        must_have_client_cert = config.get("flask.force_client_cert")

        if cFCGI:
            logger.info("registering fcgi server at %s:%i", host, fcgi_port)
            from flup.server.fcgi import WSGIServer
            WSGIServer(self._app, bindAddress=(host, fcgi_port)).run()
        else:
            logger.info("registering app server at %s:%i", host, app_port)
            # this workaround makes sure that the client cert can be acquired later (even when running the development server)
            # copied all this stuff from the actual flask implementation, so we can intervene and adjust the ssl context
            # self._app.run(host=host, port=app_port, ssl_context='adhoc', debug=debug, request_handler=ClientCertHTTPRequestHandler)

            # the code from flask's `run...`
            # see https://github.com/mitsuhiko/flask/blob/master/flask/app.py
            options = {}
            try:
                # now the code from werkzeug's `run_simple(host, app_port, self._app, **options)`
                # see https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/serving.py
                from werkzeug.debug import DebuggedApplication
                import socket
                application = DebuggedApplication(self._app, True)

                def inner():
                    server = serving.make_server(host, app_port, self._app,
                                                 False, 1,
                                                 ClientCertHTTPRequestHandler,
                                                 False, 'adhoc')
                    # The following line is the reason why I copied all that code!
                    if must_have_client_cert:
                        server.ssl_context.set_verify(
                            SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
                            lambda a, b, c, d, e: True)
                    # That's it
                    server.serve_forever()

                address_family = serving.select_ip_version(host, app_port)
                test_socket = socket.socket(address_family, socket.SOCK_STREAM)
                test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
                                       1)
                test_socket.bind((host, app_port))
                test_socket.close()
                serving.run_with_reloader(inner, None, 1)
            finally:
                self._app._got_first_request = False
Example #4
0
def run_simple(hostname,
               port,
               application,
               use_reloader=False,
               use_debugger=False,
               use_evalex=True,
               extra_files=None,
               reloader_interval=1,
               reloader_type='auto',
               threaded=False,
               processes=1,
               request_handler=None,
               static_files=None,
               passthrough_errors=False,
               ssl_context=None):
    if use_debugger:
        from werkzeug.debug import DebuggedApplication
        application = DebuggedApplication(application, use_evalex)
    if static_files:
        from werkzeug.wsgi import SharedDataMiddleware
        application = SharedDataMiddleware(application, static_files)

    def inner():
        # Override here
        make_server(hostname, port, application, threaded, processes,
                    request_handler, passthrough_errors,
                    ssl_context).serve_forever()

    if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
        display_hostname = hostname != '*' and hostname or 'localhost'
        if ':' in display_hostname:
            display_hostname = '[%s]' % display_hostname
        quit_msg = '(Press CTRL+C to quit)'
        _log('info', ' * Running on %s://%s:%d/ %s',
             ssl_context is None and 'http' or 'https', display_hostname, port,
             quit_msg)
    if use_reloader:
        # Create and destroy a socket so that any exceptions are raised before
        # we spawn a separate Python interpreter and lose this ability.
        address_family = select_ip_version(hostname, port)
        test_socket = socket.socket(address_family, socket.SOCK_STREAM)
        test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        test_socket.bind((hostname, port))
        test_socket.close()

        from werkzeug._reloader import run_with_reloader
        run_with_reloader(inner, extra_files, reloader_interval, reloader_type)
    else:
        inner()
Example #5
0
    def runServer(self):
        """Starts up the server. It (will) support different config options via the config plugin."""
        config = pm.getService("config")
        debug = config.get("flask.debug")
        cFCGI = config.get("flask.fcgi")
        host = config.get("flask.bind")
        app_port = config.get("flask.app_port")
        fcgi_port = config.get("flask.fcgi_port")
        must_have_client_cert = config.get("flask.force_client_cert")

        if cFCGI:
            logger.info("registering fcgi server at %s:%i", host, fcgi_port)
            from flup.server.fcgi import WSGIServer
            WSGIServer(self._app, bindAddress=(host, fcgi_port)).run()
        else:
            logger.info("registering app server at %s:%i", host, app_port)
            # this workaround makes sure that the client cert can be acquired later (even when running the development server)
            # copied all this stuff from the actual flask implementation, so we can intervene and adjust the ssl context
            # self._app.run(host=host, port=app_port, ssl_context='adhoc', debug=debug, request_handler=ClientCertHTTPRequestHandler)
            
            # the code from flask's `run...`
            # see https://github.com/mitsuhiko/flask/blob/master/flask/app.py
            options = {}
            try:
                # now the code from werkzeug's `run_simple(host, app_port, self._app, **options)`
                # see https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/serving.py
                from werkzeug.debug import DebuggedApplication
                import socket
                application = DebuggedApplication(self._app, True)
                def inner():
                    server = serving.make_server(host, app_port, self._app, False, 1, ClientCertHTTPRequestHandler, False, 'adhoc')
                    # The following line is the reason why I copied all that code!
                    if must_have_client_cert:
                        server.ssl_context.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, lambda a,b,c,d,e: True)
                    # That's it
                    server.serve_forever()
                address_family = serving.select_ip_version(host, app_port)
                test_socket = socket.socket(address_family, socket.SOCK_STREAM)
                test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                test_socket.bind((host, app_port))
                test_socket.close()
                serving.run_with_reloader(inner, None, 1)
            finally:
                self._app._got_first_request = False
Example #6
0
def app_port(request):
    port = 30000
    hostname = '127.0.0.1'

    address_family = select_ip_version(hostname, port)
    test_socket = socket.socket(address_family, socket.SOCK_STREAM)
    test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    while port < 60000:
        try:
            test_socket.bind((hostname, port))
            test_socket.close()

        except socket.error as exc:
            if exc.errno != 98:
                # errno(98, Address already in use)
                raise
            port += 1

        break

    return port
Example #7
0
def app_port(request):
    port = 30000
    hostname = "127.0.0.1"

    address_family = select_ip_version(hostname, port)
    test_socket = socket.socket(address_family, socket.SOCK_STREAM)
    test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    while port < 60000:
        try:
            test_socket.bind((hostname, port))
            test_socket.close()

        except socket.error as exc:
            if exc.errno != 98:
                # errno(98, Address already in use)
                raise
            port += 1

        break

    return port
Example #8
0
def run_server(hostname,
               port,
               application,
               use_reloader=False,
               reloader_interval=1,
               static_files=None,
               request_handler=WebSocketHandler):
    """"运行服务器"""
    import werkzeug
    from werkzeug._internal import _log
    from werkzeug.serving import select_ip_version, socket, run_with_reloader

    if static_files:
        from werkzeug.wsgi import SharedDataMiddleware
        application = SharedDataMiddleware(application, static_files)

    def inner():
        make_server(hostname, port, application,
                    request_handler).serve_forever()

    if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
        display_hostname = hostname != '*' and hostname or 'localhost'
        if ':' in display_hostname:
            display_hostname = '[%s]' % display_hostname
        _log('info', ' * Running on http://%s:%d/', display_hostname, port)
        if request_handler and hasattr(request_handler, 'run_websocket'):
            _log('info', ' * Running on ws://%s:%d/', display_hostname, port)

    if use_reloader:
        address_family = select_ip_version(hostname, port)
        test_socket = socket.socket(address_family, socket.SOCK_STREAM)
        test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        test_socket.bind((hostname, port))
        test_socket.close()
        run_with_reloader(inner, None, reloader_interval)
    else:
        inner()
Example #9
0
    def runServer(self, services=[]):
        """Starts up the server. It (will) support different config options via the config plugin."""
        self.add_routes()
        #debug = self.general_section.get("debug")
        host = self.general_section.get("host")
        use_reloader = ast.literal_eval(
            self.general_section.get("use_reloader"))
        app_port = int(self.general_section.get("port"))
        cFCGI = ast.literal_eval(self.fcgi_section.get("enabled"))
        fcgi_port = int(self.fcgi_section.get("port"))
        must_have_client_cert = ast.literal_eval(
            self.certificates_flask_section.get("force_client_certificate"))
        if cFCGI:
            logger.info("registering fcgi server at %s:%i", host, fcgi_port)
            from flup.server.fcgi import WSGIServer
            WSGIServer(self._app, bindAddress=(host, fcgi_port)).run()
        else:
            logger.info("registering app server at %s:%i", host, app_port)
            # this workaround makes sure that the client cert can be acquired later (even when running the development server)
            # copied all this stuff from the actual flask implementation, so we can intervene and adjust the ssl context
            # self._app.run(host=host, port=app_port, ssl_context='adhoc', debug=debug, request_handler=ClientCertHTTPRequestHandler)

            # the code from flask's `run...`
            # see https://github.com/mitsuhiko/flask/blob/master/flask/app.py
            #options = {}
            try:
                # now the code from werkzeug's `run_simple(host, app_port, self._app, **options)`
                # see https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/serving.py
                #from werkzeug.debug import DebuggedApplication
                import socket
                #application = DebuggedApplication(self._app, True)

                # Set up an SSL context
                context = SSL.Context(SSL.SSLv23_METHOD)
                certs_path = os.path.normpath(
                    os.path.join(os.path.dirname(__file__), "../../..",
                                 "cert"))
                context_crt = os.path.join(certs_path, "server.crt")
                context_key = os.path.join(certs_path, "server.key")
                try:
                    context.use_certificate_file(context_crt)
                    context.use_privatekey_file(context_key)
                except Exception as e:
                    logger.critical(
                        "error starting flask server. Cert or key is missing under %s",
                        certs_path)
                    sys.exit(e)

                def inner():
                    #server = serving.make_server(host, app_port, self._app, False, 1, ClientCertHTTPRequestHandler, False, 'adhoc')
                    server = serving.make_server(host,
                                                 app_port,
                                                 self._app,
                                                 False,
                                                 1,
                                                 ClientCertHTTPRequestHandler,
                                                 False,
                                                 ssl_context=context)
                    #server = serving.make_server(host, app_port, self._app, False, 1, ClientCertHTTPRequestHandler, False, ssl_context=(context_crt, context_key))
                    # The following line is the reason why I copied all that code!
                    if must_have_client_cert:
                        # FIXME: what works with web app does not work with cli. Check this out
                        server.ssl_context.set_verify(
                            SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
                            lambda a, b, c, d, e: True)
                    # before enter in the loop, start the supplementary services
                    for s in services:
                        s.start()
                    # That's it
                    server.serve_forever()

                address_family = serving.select_ip_version(host, app_port)
                test_socket = socket.socket(address_family, socket.SOCK_STREAM)
                test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
                                       1)
                test_socket.bind((host, app_port))
                test_socket.close()
                # Disable reloader only by explicit config setting
                if use_reloader == False:
                    serving.run_simple(host,
                                       app_port,
                                       self._app,
                                       use_reloader=False)
                else:
                    serving.run_with_reloader(inner, None, 1)
            finally:
                self._app._got_first_request = False
Example #10
0
def run_simple(hostname, port, application, use_reloader=False,
               use_debugger=False, use_evalex=True,
               extra_files=None, reloader_interval=1,
               reloader_type='auto', threaded=False, processes=1,
               request_handler=None, static_files=None,
               passthrough_errors=False, ssl_context=None, loop=None):
    """Start a WSGI application. Optional features include a reloader,
    multithreading and fork support.

    This function has a command-line interface too::

        python -m werkzeug.serving --help

    .. versionadded:: 0.5
       `static_files` was added to simplify serving of static files as well
       as `passthrough_errors`.

    .. versionadded:: 0.6
       support for SSL was added.

    .. versionadded:: 0.8
       Added support for automatically loading a SSL context from certificate
       file and private key.

    .. versionadded:: 0.9
       Added command-line interface.

    .. versionadded:: 0.10
       Improved the reloader and added support for changing the backend
       through the `reloader_type` parameter.  See :ref:`reloader`
       for more information.

    :param hostname: The host for the application.  eg: ``'localhost'``
    :param port: The port for the server.  eg: ``8080``
    :param application: the WSGI application to execute
    :param use_reloader: should the server automatically restart the python
                         process if modules were changed?
    :param use_debugger: should the werkzeug debugging system be used?
    :param use_evalex: should the exception evaluation feature be enabled?
    :param extra_files: a list of files the reloader should watch
                        additionally to the modules.  For example configuration
                        files.
    :param reloader_interval: the interval for the reloader in seconds.
    :param reloader_type: the type of reloader to use.  The default is
                          auto detection.  Valid values are ``'stat'`` and
                          ``'watchdog'``. See :ref:`reloader` for more
                          information.
    :param threaded: should the process handle each request in a separate
                     thread?
    :param processes: if greater than 1 then handle each request in a new process
                      up to this maximum number of concurrent processes.
    :param request_handler: optional parameter that can be used to replace
                            the default one.  You can use this to replace it
                            with a different
                            :class:`~BaseHTTPServer.BaseHTTPRequestHandler`
                            subclass.
    :param static_files: a dict of paths for static files.  This works exactly
                         like :class:`SharedDataMiddleware`, it's actually
                         just wrapping the application in that middleware before
                         serving.
    :param passthrough_errors: set this to `True` to disable the error catching.
                               This means that the server will die on errors but
                               it can be useful to hook debuggers in (pdb etc.)
    :param ssl_context: an SSL context for the connection. Either an
                        :class:`ssl.SSLContext`, a tuple in the form
                        ``(cert_file, pkey_file)``, the string ``'adhoc'`` if
                        the server should automatically create one, or ``None``
                        to disable SSL (which is the default).
    """
    loop = loop or asyncio.get_event_loop()

    if use_debugger:
        raise NotImplemented("Debugger not implemented with asyncio")
    if static_files:
        raise NotImplemented("Static files not implemented with asyncio")

    def inner(loop):
        make_server(hostname, port, application, threaded,
                    processes, request_handler,
                    passthrough_errors, ssl_context, loop)

    if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
        display_hostname = hostname != '*' and hostname or 'localhost'
        if ':' in display_hostname:
            display_hostname = '[%s]' % display_hostname
        quit_msg = '(Press CTRL+C to quit)'
        _log('info', ' * Running on %s://%s:%d/ %s', ssl_context is None
             and 'http' or 'https', display_hostname, port, quit_msg)
    if use_reloader:
        # Create and destroy a socket so that any exceptions are raised before
        # we spawn a separate Python interpreter and lose this ability.
        address_family = select_ip_version(hostname, port)
        test_socket = socket.socket(address_family, socket.SOCK_STREAM)
        test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        test_socket.bind((hostname, port))
        test_socket.close()

        from ._reloader import run_with_reloader
        run_with_reloader(inner, extra_files, reloader_interval,
                          reloader_type, loop)
    else:
        inner(loop)
        loop.run_forever()
Example #11
0
def run_simple(hostname,
               port,
               application,
               use_reloader=False,
               use_debugger=False,
               use_evalex=True,
               extra_files=None,
               reloader_interval=1,
               reloader_type='auto',
               threaded=False,
               processes=1,
               request_handler=None,
               static_files=None,
               passthrough_errors=False,
               ssl_context=None,
               loop=None):
    """Start a WSGI application. Optional features include a reloader,
    multithreading and fork support.

    This function has a command-line interface too::

        python -m werkzeug.serving --help

    .. versionadded:: 0.5
       `static_files` was added to simplify serving of static files as well
       as `passthrough_errors`.

    .. versionadded:: 0.6
       support for SSL was added.

    .. versionadded:: 0.8
       Added support for automatically loading a SSL context from certificate
       file and private key.

    .. versionadded:: 0.9
       Added command-line interface.

    .. versionadded:: 0.10
       Improved the reloader and added support for changing the backend
       through the `reloader_type` parameter.  See :ref:`reloader`
       for more information.

    :param hostname: The host for the application.  eg: ``'localhost'``
    :param port: The port for the server.  eg: ``8080``
    :param application: the WSGI application to execute
    :param use_reloader: should the server automatically restart the python
                         process if modules were changed?
    :param use_debugger: should the werkzeug debugging system be used?
    :param use_evalex: should the exception evaluation feature be enabled?
    :param extra_files: a list of files the reloader should watch
                        additionally to the modules.  For example configuration
                        files.
    :param reloader_interval: the interval for the reloader in seconds.
    :param reloader_type: the type of reloader to use.  The default is
                          auto detection.  Valid values are ``'stat'`` and
                          ``'watchdog'``. See :ref:`reloader` for more
                          information.
    :param threaded: should the process handle each request in a separate
                     thread?
    :param processes: if greater than 1 then handle each request in a new process
                      up to this maximum number of concurrent processes.
    :param request_handler: optional parameter that can be used to replace
                            the default one.  You can use this to replace it
                            with a different
                            :class:`~BaseHTTPServer.BaseHTTPRequestHandler`
                            subclass.
    :param static_files: a dict of paths for static files.  This works exactly
                         like :class:`SharedDataMiddleware`, it's actually
                         just wrapping the application in that middleware before
                         serving.
    :param passthrough_errors: set this to `True` to disable the error catching.
                               This means that the server will die on errors but
                               it can be useful to hook debuggers in (pdb etc.)
    :param ssl_context: an SSL context for the connection. Either an
                        :class:`ssl.SSLContext`, a tuple in the form
                        ``(cert_file, pkey_file)``, the string ``'adhoc'`` if
                        the server should automatically create one, or ``None``
                        to disable SSL (which is the default).
    """
    loop = loop or asyncio.get_event_loop()

    if use_debugger:
        raise NotImplemented("Debugger not implemented with asyncio")
    if static_files:
        raise NotImplemented("Static files not implemented with asyncio")

    def inner(loop):
        make_server(hostname, port, application, threaded, processes,
                    request_handler, passthrough_errors, ssl_context, loop)

    if os.environ.get('WERKZEUG_RUN_MAIN') != 'true':
        display_hostname = hostname != '*' and hostname or 'localhost'
        if ':' in display_hostname:
            display_hostname = '[%s]' % display_hostname
        quit_msg = '(Press CTRL+C to quit)'
        _log('info', ' * Running on %s://%s:%d/ %s',
             ssl_context is None and 'http' or 'https', display_hostname, port,
             quit_msg)
    if use_reloader:
        # Create and destroy a socket so that any exceptions are raised before
        # we spawn a separate Python interpreter and lose this ability.
        address_family = select_ip_version(hostname, port)
        test_socket = socket.socket(address_family, socket.SOCK_STREAM)
        test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        test_socket.bind((hostname, port))
        test_socket.close()

        from ._reloader import run_with_reloader
        run_with_reloader(inner, extra_files, reloader_interval, reloader_type,
                          loop)
    else:
        inner(loop)
        loop.run_forever()
Example #12
0
    def runServer(self, services=[]):
        """Starts up the server. It (will) support different config options via the config plugin."""
        self.add_routes()
        debug = self.general_section.get("debug")
        host = self.general_section.get("host")
        app_port = int(self.general_section.get("port"))
        template_folder = self.general_section.get("template_folder")
        cFCGI = ast.literal_eval(self.fcgi_section.get("enabled"))
        fcgi_port = int(self.fcgi_section.get("port"))
        must_have_client_cert = ast.literal_eval(self.certificates_section.get("force_client_certificate"))
        if cFCGI:
            logger.info("registering fcgi server at %s:%i", host, fcgi_port)
            from flup.server.fcgi import WSGIServer
            WSGIServer(self._app, bindAddress=(host, fcgi_port)).run()
        else:
            logger.info("registering app server at %s:%i", host, app_port)
            # this workaround makes sure that the client cert can be acquired later (even when running the development server)
            # copied all this stuff from the actual flask implementation, so we can intervene and adjust the ssl context
            # self._app.run(host=host, port=app_port, ssl_context='adhoc', debug=debug, request_handler=ClientCertHTTPRequestHandler)

            # the code from flask's `run...`
            # see https://github.com/mitsuhiko/flask/blob/master/flask/app.py
            options = {}
            try:
                # now the code from werkzeug's `run_simple(host, app_port, self._app, **options)`
                # see https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/serving.py
                from werkzeug.debug import DebuggedApplication
                import socket
                application = DebuggedApplication(self._app, True)
                
                # Set up an SSL context
                from OpenSSL import SSL
                context = SSL.Context(SSL.SSLv23_METHOD)
                certs_path = os.path.normpath(os.path.join(os.path.dirname(__file__), "../../..", "cert"))
                context_crt = os.path.join(certs_path, "server.crt")
                context_key = os.path.join(certs_path, "server.key")
                try:
                    context.use_certificate_file(context_crt)
                    context.use_privatekey_file(context_key)
                except Exception as e:
                    logger.critical("error starting flask server. Cert or key is missing under %s", certs_path)
                    sys.exit(e)
                
                def inner():
                    #server = serving.make_server(host, app_port, self._app, False, 1, ClientCertHTTPRequestHandler, False, 'adhoc')
                    server = serving.make_server(host, app_port, self._app, False, 1, ClientCertHTTPRequestHandler, False, ssl_context=context)
                    #server = serving.make_server(host, app_port, self._app, False, 1, ClientCertHTTPRequestHandler, False, ssl_context=(context_crt, context_key))
                    # The following line is the reason why I copied all that code!
                    if must_have_client_cert:
                        # FIXME: what works with web app does not work with cli. Check this out
                        server.ssl_context.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, lambda a,b,c,d,e: True)
                    # before enter in the loop, start the supplementary services
                    for s in services:
                        s.start()
                    # That's it
                    server.serve_forever()
                address_family = serving.select_ip_version(host, app_port)
                test_socket = socket.socket(address_family, socket.SOCK_STREAM)
                test_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                test_socket.bind((host, app_port))
                test_socket.close()
                serving.run_with_reloader(inner, None, 1)
            finally:
                self._app._got_first_request = False