Exemplo n.º 1
0
    def test_close(self):
        reactor = Reactor()
        thread = concurrent.thread(reactor.process_requests, name="test ractor")
        thread.start()
        s1, s2 = socket.socketpair()
        with closing(s2):
            disp = reactor.create_dispatcher(s1, impl=TestingImpl())
            reactor.stop()

        thread.join(timeout=1)

        self.assertTrue(disp.closing)
        self.assertFalse(reactor._wakeupEvent.closing)
Exemplo n.º 2
0
    def test_close(self):
        reactor = Reactor()
        thread = concurrent.thread(reactor.process_requests,
                                   name='test ractor')
        thread.start()
        s1, s2 = socket.socketpair()
        with closing(s2):
            disp = reactor.create_dispatcher(s1, impl=TestingImpl())
            reactor.stop()

        thread.join(timeout=1)

        self.assertTrue(disp.closing)
        self.assertFalse(reactor._wakeupEvent.closing)
Exemplo n.º 3
0
class MultiProtocolAcceptor:
    """
    Provides multiple protocol support on a single port.

    MultiProtocolAcceptor binds and listen on a single port. It accepts
    incoming connections and handles handshake if required. Next it peeks
    into the first bytes sent to detect the protocol, and pass the connection
    to the server handling this protocol.

    To support a new protocol, register a detector object using
    add_detector. Protocol detectors must implement this interface:

    class ProtocolDetector(object):
        NAME = "protocol name"

        # How many bytes are needed to detect this protocol
        REQUIRED_SIZE = 6

        def detect(self, data):
            Given first bytes read from the connection, try to detect the
            protocol. Returns True if protocol is detected.

        def handle_dispatcher(self, client_dispatcher, socket_address):
            Called after detect() succeeded. The detector owns the socket and
            is responsible for closing it or changing the implementation.
    """
    log = logging.getLogger("vds.MultiProtocolAcceptor")

    def __init__(
        self,
        host,
        port,
        sslctx=None,
        ssl_hanshake_timeout=SSLHandshakeDispatcher.SSL_HANDSHAKE_TIMEOUT,
    ):
        self._sslctx = sslctx
        self._reactor = Reactor()
        sock = _create_socket(host, port)
        self._host, self._port = sock.getsockname()
        self.log.info("Listening at %s:%d", self._host, self._port)
        self._acceptor = self._reactor.create_dispatcher(
            sock, _AcceptorImpl(self.handle_accept))
        self._acceptor.listen(5)
        self._handlers = []
        self.TIMEOUT = ssl_hanshake_timeout

    def handle_accept(self, client):
        if self._sslctx is None:
            dispatcher = self._reactor.create_dispatcher(client)
            self._register_protocol_detector(dispatcher)
        else:
            dispatcher = SSLHandshakeDispatcher(
                self._sslctx, self._register_protocol_detector, self.TIMEOUT)
            self._reactor.create_dispatcher(client, dispatcher)

    def _register_protocol_detector(self, dispatcher):
        dispatcher.switch_implementation(
            _ProtocolDetector(
                self._handlers,
                self.TIMEOUT,
            ),
        )

        return dispatcher

    @traceback(on=log.name)
    def serve_forever(self):
        self.log.debug("Running")
        self._reactor.process_requests()

    def add_detector(self, detector):
        self.log.debug("Adding detector %s", detector)
        self._handlers.append(detector)

    def stop(self):
        self.log.debug("Stopping Acceptor")
        self._reactor.stop()
Exemplo n.º 4
0
class MultiProtocolAcceptor:
    """
    Provides multiple protocol support on a single port.

    MultiProtocolAcceptor binds and listen on a single port. It accepts
    incoming connections and handles handshake if required. Next it peeks
    into the first bytes sent to detect the protocol, and pass the connection
    to the server handling this protocol.

    To support a new protocol, register a detector object using
    add_detector. Protocol detectors must implement this interface:

    class ProtocolDetector(object):
        NAME = "protocol name"

        # How many bytes are needed to detect this protocol
        REQUIRED_SIZE = 6

        def detect(self, data):
            Given first bytes read from the connection, try to detect the
            protocol. Returns True if protocol is detected.

        def handle_dispatcher(self, client_dispatcher, socket_address):
            Called after detect() succeeded. The detector owns the socket and
            is responsible for closing it or changing the implementation.
    """
    log = logging.getLogger("vds.MultiProtocolAcceptor")

    def __init__(
        self,
        host,
        port,
        sslctx=None,
        ssl_hanshake_timeout=SSLHandshakeDispatcher.SSL_HANDSHAKE_TIMEOUT,
    ):
        self._sslctx = sslctx
        self._reactor = Reactor()
        sock = _create_socket(host, port)
        self._host, self._port = sock.getsockname()
        self.log.info("Listening at %s:%d", self._host, self._port)
        self._acceptor = self._reactor.create_dispatcher(
            sock, _AcceptorImpl(self.handle_accept))
        self._acceptor.listen(5)
        self._handlers = []
        self.TIMEOUT = ssl_hanshake_timeout

    def handle_accept(self, client):
        if self._sslctx is None:
            dispatcher = self._reactor.create_dispatcher(client)
            self._register_protocol_detector(dispatcher)
        else:
            dispatcher = SSLHandshakeDispatcher(
                self._sslctx, self._register_protocol_detector, self.TIMEOUT)
            self._reactor.create_dispatcher(client, dispatcher)

    def _register_protocol_detector(self, dispatcher):
        dispatcher.switch_implementation(
            _ProtocolDetector(
                self._handlers,
                self.TIMEOUT,
            ), )

        return dispatcher

    @traceback(on=log.name)
    def serve_forever(self):
        self.log.debug("Running")
        self._reactor.process_requests()

    def add_detector(self, detector):
        self.log.debug("Adding detector %s", detector)
        self._handlers.append(detector)

    def stop(self):
        self.log.debug("Stopping Acceptor")
        self._reactor.stop()