Ejemplo n.º 1
0
 def _reinit_kqueue(self):
     self.kqueue.close()
     self._init_kqueue()
     kqueue = self.kqueue
     events = [e for i in six.itervalues(self._events)
               for e in six.itervalues(i)]
     kqueue.control(events, 0, 0)
Ejemplo n.º 2
0
 def _reinit_kqueue(self):
     self.kqueue.close()
     self._init_kqueue()
     kqueue = self.kqueue
     events = [e for i in six.itervalues(self._events)
               for e in six.itervalues(i)]
     kqueue.control(events, 0, 0)
Ejemplo n.º 3
0
 def remove_descriptor(self, fileno):
     for lcontainer in six.itervalues(self.listeners):
         listener = lcontainer.pop(fileno, None)
         if listener:
             try:
                 listener.cb.delete()
             except self.SYSTEM_EXCEPTIONS:
                 raise
             except:
                 traceback.print_exc()
Ejemplo n.º 4
0
def server(sock, site,
           log=None,
           environ=None,
           max_size=None,
           max_http_version=DEFAULT_MAX_HTTP_VERSION,
           protocol=HttpProtocol,
           server_event=None,
           minimum_chunk_size=None,
           log_x_forwarded_for=True,
           custom_pool=None,
           keepalive=True,
           log_output=True,
           log_format=DEFAULT_LOG_FORMAT,
           url_length_limit=MAX_REQUEST_LINE,
           debug=True,
           socket_timeout=None,
           capitalize_response_headers=True):
    """Start up a WSGI server handling requests from the supplied server
    socket.  This function loops forever.  The *sock* object will be
    closed after server exits, but the underlying file descriptor will
    remain open, so if you have a dup() of *sock*, it will remain usable.

    .. warning::

        At the moment :func:`server` will always wait for active connections to finish before
        exiting, even if there's an exception raised inside it
        (*all* exceptions are handled the same way, including :class:`greenlet.GreenletExit`
        and those inheriting from `BaseException`).

        While this may not be an issue normally, when it comes to long running HTTP connections
        (like :mod:`eventlet.websocket`) it will become problematic and calling
        :meth:`~eventlet.greenthread.GreenThread.wait` on a thread that runs the server may hang,
        even after using :meth:`~eventlet.greenthread.GreenThread.kill`, as long
        as there are active connections.

    :param sock: Server socket, must be already bound to a port and listening.
    :param site: WSGI application function.
    :param log: logging.Logger instance or file-like object that logs should be written to.
                If a Logger instance is supplied, messages are sent to the INFO log level.
                If not specified, sys.stderr is used.
    :param environ: Additional parameters that go into the environ dictionary of every request.
    :param max_size: Maximum number of client connections opened at any time by this server.
                Default is 1024.
    :param max_http_version: Set to "HTTP/1.0" to make the server pretend it only supports HTTP 1.0.
                This can help with applications or clients that don't behave properly using HTTP 1.1.
    :param protocol: Protocol class.  Deprecated.
    :param server_event: Used to collect the Server object.  Deprecated.
    :param minimum_chunk_size: Minimum size in bytes for http chunks.  This can be used to improve
                performance of applications which yield many small strings, though
                using it technically violates the WSGI spec. This can be overridden
                on a per request basis by setting environ['eventlet.minimum_write_chunk_size'].
    :param log_x_forwarded_for: If True (the default), logs the contents of the x-forwarded-for
                header in addition to the actual client ip address in the 'client_ip' field of the
                log line.
    :param custom_pool: A custom GreenPool instance which is used to spawn client green threads.
                If this is supplied, max_size is ignored.
    :param keepalive: If set to False, disables keepalives on the server; all connections will be
                closed after serving one request.
    :param log_output: A Boolean indicating if the server will log data or not.
    :param log_format: A python format string that is used as the template to generate log lines.
                The following values can be formatted into it: client_ip, date_time, request_line,
                status_code, body_length, wall_seconds.  The default is a good example of how to
                use it.
    :param url_length_limit: A maximum allowed length of the request url. If exceeded, 414 error
                is returned.
    :param debug: True if the server should send exception tracebacks to the clients on 500 errors.
                If False, the server will respond with empty bodies.
    :param socket_timeout: Timeout for client connections' socket operations. Default None means
                wait forever.
    :param capitalize_response_headers: Normalize response headers' names to Foo-Bar.
                Default is True.
    """
    serv = Server(
        sock, sock.getsockname(),
        site, log,
        environ=environ,
        max_http_version=max_http_version,
        protocol=protocol,
        minimum_chunk_size=minimum_chunk_size,
        log_x_forwarded_for=log_x_forwarded_for,
        keepalive=keepalive,
        log_output=log_output,
        log_format=log_format,
        url_length_limit=url_length_limit,
        debug=debug,
        socket_timeout=socket_timeout,
        capitalize_response_headers=capitalize_response_headers,
    )
    if server_event is not None:
        warnings.warn(
            'eventlet.wsgi.Server() server_event kwarg is deprecated and will be removed soon',
            DeprecationWarning, stacklevel=2)
        server_event.send(serv)
    if max_size is None:
        max_size = DEFAULT_MAX_SIMULTANEOUS_REQUESTS
    if custom_pool is not None:
        pool = custom_pool
    else:
        pool = eventlet.GreenPool(max_size)

    if not (hasattr(pool, 'spawn') and hasattr(pool, 'waitall')):
        raise AttributeError('''\
eventlet.wsgi.Server pool must provide methods: `spawn`, `waitall`.
If unsure, use eventlet.GreenPool.''')

    # [addr, socket, state]
    connections = {}

    def _clean_connection(_, conn):
        connections.pop(conn[0], None)
        conn[2] = STATE_CLOSE
        greenio.shutdown_safe(conn[1])
        conn[1].close()

    try:
        serv.log.info('({0}) wsgi starting up on {1}'.format(serv.pid, socket_repr(sock)))
        while is_accepting:
            try:
                client_socket, client_addr = sock.accept()
                client_socket.settimeout(serv.socket_timeout)
                serv.log.debug('({0}) accepted {1!r}'.format(serv.pid, client_addr))
                connections[client_addr] = connection = [client_addr, client_socket, STATE_IDLE]
                (pool.spawn(serv.process_request, connection)
                    .link(_clean_connection, connection))
            except ACCEPT_EXCEPTIONS as e:
                if support.get_errno(e) not in ACCEPT_ERRNO:
                    raise
            except (KeyboardInterrupt, SystemExit):
                serv.log.info('wsgi exiting')
                break
    finally:
        for cs in six.itervalues(connections):
            prev_state = cs[2]
            cs[2] = STATE_CLOSE
            if prev_state == STATE_IDLE:
                greenio.shutdown_safe(cs[1])
        pool.waitall()
        serv.log.info('({0}) wsgi exited, is_accepting={1}'.format(serv.pid, is_accepting))
        try:
            # NOTE: It's not clear whether we want this to leave the
            # socket open or close it.  Use cases like Spawning want
            # the underlying fd to remain open, but if we're going
            # that far we might as well not bother closing sock at
            # all.
            sock.close()
        except socket.error as e:
            if support.get_errno(e) not in BROKEN_SOCK:
                traceback.print_exc()