Example #1
0
    def __init__(self, wsgi_apps=(), stream_handlers=(), custom_servers=(),
                 prefork=None, daemonize=None, **kw):
        """\
        Create a new Group of servers which can be started/stopped/forked
        as a group.

        *wsgi_apps* should be of the form  [ (wsgi_app, address, ssl), ...  ]

        *stream_handlers* should be of the form  [ (handler_func, address), ...  ]

        *custom_servers* should be of the form [ (server_class, address), ... ]
        where server_class refers to subclasses of gevent.server.StreamServer
        which define their own handle function

        address here refers to a tuple (ip, port), or more generally anything which is
        acceptable as the address parameter to
        `socket.bind() <http://docs.python.org/2/library/socket.html#socket.socket.bind>`_.

        `handler_func` should have the following signature: f(socket, address), following
        the `convention of gevent <http://www.gevent.org/servers.html>`_.
        """
        ctx = context.get_context()
        self.wsgi_apps = list(wsgi_apps or [])
        self.stream_handlers = list(stream_handlers or [])
        self.custom_servers = list(custom_servers or [])

        self.prefork = prefork
        self.daemonize = daemonize
        # max number of concurrent clients per worker
        self.max_clients = kw.pop('max_clients', DEFAULT_MAX_CLIENTS)
        self.num_workers = kw.pop('num_workers', DEFAULT_NUM_WORKERS)
        self.post_fork = kw.pop('post_fork', None)  # post-fork callback
        self.server_log = kw.pop('gevent_log', None)

        self.meta_address = kw.pop('meta_address', None)
        self.console_address = kw.pop('console_address', None)
        self._require_client_auth = kw.pop('require_client_auth', True)

        if kw:
            raise TypeError('unexpected keyword args: %r' % kw.keys())

        self.client_pool = gevent.pool.Pool(ctx.max_concurrent_clients)
        self.servers = []
        self.socks = {}

        # we do NOT want a gevent socket if we're going to use a
        # thread to manage our accepts; it's critical that the
        # accept() call *blocks*
        socket_type = gevent.socket.socket if not ufork else socket.socket

        for app, address, ssl in wsgi_apps:
            sock = _make_server_sock(address, socket_type=socket_type)

            if isinstance(ssl, SSLContext):
                ssl_context = ssl
            elif ssl:
                ssl_context = ctx.ssl_context
            else:
                ssl_context = None
            if ssl_context:
                if self._no_client_auth_req:
                    server = MultiProtocolWSGIServer(
                        sock, app, spawn=self.client_pool, context=ssl_context)
                else:
                    server = SslContextWSGIServer(
                        sock, app, spawn=self.client_pool, context=ssl_context)
            else:
                server = ThreadQueueWSGIServer(sock, app)
            server.log = self.server_log or RotatingGeventLog()
            self.servers.append(server)
            self.socks[server] = sock
            # prevent a "blocking" call to DNS on each request
            # (NOTE: although the OS won't block, gevent will dispatch
            # to a threadpool which is expensive)
            server.set_environ({'SERVER_NAME': socket.getfqdn(address[0]),
                                'wsgi.multiprocess': True})
        for handler, address in self.stream_handlers:
            sock = _make_server_sock(address)
            server = gevent.server.StreamServer(sock, handler, spawn=self.client_pool)
            self.servers.append(server)
        for server_class, address in self.custom_servers:
            # our stated requirement is that users provide a subclass
            # of StreamServer, which would *not* know about our thread
            # queue.  consequently we can't give it a blocking socket
            sock = _make_server_sock(address)
            server = server_class(sock, spawn=self.client_pool)
            self.servers.append(server)
        if self.console_address is not None:
            try:
                sock = _make_server_sock(self.console_address)
            except Exception as e:
                print "WARNING: unable to start backdoor server on port", ctx.backdoor_port, repr(e)
            else:
                server = gevent.server.StreamServer(sock, console_sock_handle, spawn=self.client_pool)
                self.servers.append(server)
        # set all servers max_accept to 1 since we are in a pre-forked/multiprocess environment
        for server in self.servers:
            server.max_accept = 1
Example #2
0
    def __init__(self,
                 wsgi_apps=(),
                 stream_handlers=(),
                 custom_servers=(),
                 prefork=None,
                 daemonize=None,
                 socket_ark_self=None,
                 socket_ark_peer=None,
                 socket_ark_secret='secret',
                 **kw):
        ctx = context.get_context()
        self.wsgi_apps = list(wsgi_apps or [])
        self.stream_handlers = list(stream_handlers or [])
        self.custom_servers = list(custom_servers or [])

        self.prefork = prefork
        self.daemonize = daemonize
        # max number of concurrent clients per worker
        self.max_clients = kw.pop('max_clients', DEFAULT_MAX_CLIENTS)
        self.num_workers = kw.pop('num_workers', DEFAULT_NUM_WORKERS)
        self.post_fork = kw.pop('post_fork', None)  # post-fork callback
        self.server_log = kw.pop('gevent_log', None)

        self.meta_address = kw.pop('meta_address', None)
        self.console_address = kw.pop('console_address', None)
        self._require_client_auth = kw.pop('require_client_auth', True)

        if kw:
            raise TypeError('unexpected keyword args: %r' % kw.keys())

        self.client_pool = gevent.pool.Pool(ctx.max_concurrent_clients)
        self.servers = []
        self.socks = {}

        # setup socket ark if keeping sockets alive
        self._init_socket_ark(socket_ark_self, socket_ark_peer,
                              socket_ark_secret)

        # we do NOT want a gevent socket if we're going to use a
        # thread to manage our accepts; it's critical that the
        # accept() call *blocks*
        socket_type = gevent.socket.socket if not ufork else socket.socket

        for app, address, ssl in wsgi_apps:
            sock = self.acquire_server_sock(address, socket_type=socket_type)

            if isinstance(ssl, SSLContext):
                ssl_context = ssl
            elif ssl:
                ssl_context = ctx.ssl_context
            else:
                ssl_context = None
            if ssl_context:
                if self._no_client_auth_req:
                    server = MultiProtocolWSGIServer(sock,
                                                     app,
                                                     spawn=self.client_pool,
                                                     context=ssl_context)
                else:
                    server = SslContextWSGIServer(sock,
                                                  app,
                                                  spawn=self.client_pool,
                                                  context=ssl_context)
            else:
                server = ThreadQueueWSGIServer(sock, app)
            server.log = self.server_log or RotatingGeventLog()
            self.servers.append(server)
            self.socks[server] = sock
            # prevent a "blocking" call to DNS on each request
            # (NOTE: although the OS won't block, gevent will dispatch
            # to a threadpool which is expensive)
            server.set_environ({
                'SERVER_NAME': socket.getfqdn(address[0]),
                'wsgi.multiprocess': True
            })
        for handler, address in self.stream_handlers:
            sock = self.acquire_server_sock(address)
            server = gevent.server.StreamServer(sock,
                                                handler,
                                                spawn=self.client_pool)
            self.servers.append(server)
        for server_class, address in self.custom_servers:
            # our stated requirement is that users provide a subclass
            # of StreamServer, which would *not* know about our thread
            # queue.  consequently we can't give it a blocking socket
            sock = self.acquire_server_sock(address)
            server = server_class(sock, spawn=self.client_pool)
            self.servers.append(server)
        if self.console_address is not None:
            try:
                sock = self.acquire_server_sock(self.console_address)
            except Exception as e:
                print "WARNING: unable to start backdoor server on port", ctx.backdoor_port, repr(
                    e)
            else:
                server = gevent.server.StreamServer(sock,
                                                    console_sock_handle,
                                                    spawn=self.client_pool)
                self.servers.append(server)
        # set all servers max_accept to 1 since we are in a pre-forked/multiprocess environment
        for server in self.servers:
            server.max_accept = 1
Example #3
0
    def __init__(self, wsgi_apps=(), stream_handlers=(), custom_servers=(),
                 prefork=None, daemonize=None, socket_ark_self=None,
                 socket_ark_peer=None, socket_ark_secret='secret', **kw):
        ctx = context.get_context()
        self.wsgi_apps = list(wsgi_apps or [])
        self.stream_handlers = list(stream_handlers or [])
        self.custom_servers = list(custom_servers or [])

        self.prefork = prefork
        self.daemonize = daemonize
        # max number of concurrent clients per worker
        self.max_clients = kw.pop('max_clients', DEFAULT_MAX_CLIENTS)
        self.num_workers = kw.pop('num_workers', DEFAULT_NUM_WORKERS)
        self.post_fork = kw.pop('post_fork', None)  # post-fork callback
        self.server_log = kw.pop('gevent_log', None)

        self.meta_address = kw.pop('meta_address', None)
        self.console_address = kw.pop('console_address', None)
        self._require_client_auth = kw.pop('require_client_auth', True)

        if kw:
            raise TypeError('unexpected keyword args: %r' % kw.keys())

        self.client_pool = gevent.pool.Pool(ctx.max_concurrent_clients)
        self.servers = []
        self.socks = {}

        # setup socket ark if keeping sockets alive
        self._init_socket_ark(socket_ark_self, socket_ark_peer, socket_ark_secret)

        # we do NOT want a gevent socket if we're going to use a
        # thread to manage our accepts; it's critical that the
        # accept() call *blocks*
        socket_type = gevent.socket.socket if not ufork else socket.socket

        for app, address, ssl in wsgi_apps:
            sock = self.acquire_server_sock(address, socket_type=socket_type)

            if isinstance(ssl, SSLContext):
                ssl_context = ssl
            elif ssl:
                ssl_context = ctx.ssl_context
            else:
                ssl_context = None
            if ssl_context:
                if self._no_client_auth_req:
                    server = MultiProtocolWSGIServer(
                        sock, app, spawn=self.client_pool, context=ssl_context)
                else:
                    server = SslContextWSGIServer(
                        sock, app, spawn=self.client_pool, context=ssl_context)
            else:
                server = ThreadQueueWSGIServer(sock, app)
            server.log = self.server_log or RotatingGeventLog()
            self.servers.append(server)
            self.socks[server] = sock
            # prevent a "blocking" call to DNS on each request
            # (NOTE: although the OS won't block, gevent will dispatch
            # to a threadpool which is expensive)
            server.set_environ({'SERVER_NAME': socket.getfqdn(address[0]),
                                'wsgi.multiprocess': True})
        for handler, address in self.stream_handlers:
            sock = self.acquire_server_sock(address)
            server = gevent.server.StreamServer(sock, handler, spawn=self.client_pool)
            self.servers.append(server)
        for server_class, address in self.custom_servers:
            # our stated requirement is that users provide a subclass
            # of StreamServer, which would *not* know about our thread
            # queue.  consequently we can't give it a blocking socket
            sock = self.acquire_server_sock(address)
            server = server_class(sock, spawn=self.client_pool)
            self.servers.append(server)
        if self.console_address is not None:
            try:
                sock = self.acquire_server_sock(self.console_address)
            except Exception as e:
                print "WARNING: unable to start backdoor server on port", ctx.backdoor_port, repr(e)
            else:
                server = gevent.server.StreamServer(sock, console_sock_handle, spawn=self.client_pool)
                self.servers.append(server)
        # set all servers max_accept to 1 since we are in a pre-forked/multiprocess environment
        for server in self.servers:
            server.max_accept = 1