Exemple #1
0
    def _hostpeertest(self, get, testServer):
        """
        Test one of the permutations of client/server host/peer.
        """
        class TestProtocol(Protocol):
            def makeConnection(self, transport):
                Protocol.makeConnection(self, transport)
                self.onConnection.callback(transport)

        if testServer:
            server = TestProtocol()
            d = server.onConnection = Deferred()
            client = Protocol()
        else:
            server = Protocol()
            client = TestProtocol()
            d = client.onConnection = Deferred()

        loopback.loopbackAsync(server, client)

        def connected(transport):
            host = getattr(transport, get)()
            self.assertTrue(IAddress.providedBy(host))

        return d.addCallback(connected)
Exemple #2
0
    def test_pumpPolicy(self):
        """
        The callable passed as the value for the C{pumpPolicy} parameter to
        L{loopbackAsync} is called with a L{_LoopbackQueue} of pending bytes
        and a protocol to which they should be delivered.
        """
        pumpCalls = []

        def dummyPolicy(queue, target):
            bytes = []
            while queue:
                bytes.append(queue.get())
            pumpCalls.append((target, bytes))

        client = Protocol()
        server = Protocol()

        finished = loopback.loopbackAsync(server, client, dummyPolicy)
        self.assertEquals(pumpCalls, [])

        client.transport.write("foo")
        client.transport.write("bar")
        server.transport.write("baz")
        server.transport.write("quux")
        server.transport.loseConnection()

        def cbComplete(ignored):
            self.assertEquals(
                pumpCalls,
                # The order here is somewhat arbitrary.  The implementation
                # happens to always deliver data to the client first.
                [(client, ["baz", "quux", None]), (server, ["foo", "bar"])])

        finished.addCallback(cbComplete)
        return finished
Exemple #3
0
    def _testStreamingProducer(self, mode):
        """
        Connect a couple protocol/transport pairs to an L{IOPump} and then pump
        it.  Verify that a streaming producer registered with one of the
        transports does not receive invalid L{IPushProducer} method calls and
        ends in the right state.

        @param mode: C{u"server"} to test a producer registered with the
            server transport.  C{u"client"} to test a producer registered with
            the client transport.
        """
        serverProto = Protocol()
        serverTransport = FakeTransport(serverProto, isServer=True)

        clientProto = Protocol()
        clientTransport = FakeTransport(clientProto, isServer=False)

        pump = connect(
            serverProto,
            serverTransport,
            clientProto,
            clientTransport,
            greet=False,
        )

        producer = StrictPushProducer()
        victim = {
            u"server": serverTransport,
            u"client": clientTransport,
        }[mode]
        victim.registerProducer(producer, streaming=True)

        pump.pump()
        self.assertEqual(u"running", producer._state)
Exemple #4
0
    def test_removeAll(self):
        """
        Calling C{removeAll} on a reactor includes descriptors that are
        filesystem files.
        """
        reactor = self.buildReactor()
        self.addCleanup(self.unbuildReactor, reactor)

        path = self.mktemp()
        open(path, "wb").close()

        # Cleanup might fail if file is GCed too soon:
        self.f = f = open(path, "rb")

        # Have the reader added:
        stdio = StandardIO(
            Protocol(),
            stdin=f.fileno(),
            stdout=self.extraFile.fileno(),
            reactor=reactor,
        )
        # And then removed:
        removed = reactor.removeAll()
        self.assertIn(stdio._reader, removed)
        self.assertNotIn(stdio._reader, reactor.getReaders())
Exemple #5
0
    def find_thermostats(self):
        """ Scan the subnet to find all the thermostats or anything serving
        on the port 8888
        
        """
        ip, port = self.address.split(':')
        subnet = ip.split(".")[0:2]
        ds = []
        for i in range(255):
            point = TCP4ClientEndpoint(reactor, ".".join(subnet+[i]), port)
            d = connectProtocol(point, Protocol())
            d.addTimeout(1, reactor)
            ds.append(d)

        def on_results(results):
            addrs = []
            for i, result in enumerate(results):
                success, p = result
                if success:
                    addrs.append("{}:{}".format(
                            ".".join(subnet+[i]), port))
                    p.transport.loseConnection()
            self.addresses = addrs

        DeferredList(ds, consumeErrors=True).addCallback(on_results)
Exemple #6
0
    def scan_subnet(self):
        """ Scan to find any ws clients on the port"""
        subnet = self.address.split('.')[0:3]
        addrs = []

        def on_connect(p, addr):
            log.debug("scan | {}:{} is up!".format(addr, self.port))
            addrs.append(addr)
            p.transport.loseConnection()

        #: Scan for everything in the subnet
        #: timeout after 1 second
        ds = []
        for i in range(256):
            addr = ".".join(subnet + [str(i)])
            point = TCP4ClientEndpoint(reactor, addr, self.port)
            d = connectProtocol(point, Protocol())
            d.addCallback(lambda p, addr=addr: on_connect(p, addr))
            d.addErrback(lambda e, addr=addr: log.debug("scan | {} is down".
                                                        format(addr)))
            reactor.callLater(1, d.cancel)
            ds.append(d)

        #: When they all finish update the addresses property
        done = DeferredList(ds)
        done.addCallback(lambda r: setattr(self, 'addresses', addrs))
Exemple #7
0
 def test_renderSecureRequest(self):
     """
     When the rendered request is over HTTPS, L{WebSocketsResource} wraps
     the protocol of the C{TLSMemoryBIOProtocol} instance.
     """
     request = DummyRequest("/")
     request.requestHeaders = Headers()
     transport = StringTransportWithDisconnection()
     secureProtocol = TLSMemoryBIOProtocol(Factory(), Protocol())
     transport.protocol = secureProtocol
     request.transport = transport
     request.headers.update({
         "upgrade": "Websocket",
         "connection": "Upgrade",
         "sec-websocket-key": "secure",
         "sec-websocket-version": "13"
     })
     result = self.resource.render(request)
     self.assertEqual(NOT_DONE_YET, result)
     self.assertEqual(
         {
             "connection": "Upgrade",
             "upgrade": "WebSocket",
             "sec-websocket-accept": "oYBv54i42V5dw6KnZqOFroecUTc="
         }, request.outgoingHeaders)
     self.assertEqual([""], request.written)
     self.assertEqual(101, request.responseCode)
     self.assertIdentical(None, request.transport)
     self.assertIsInstance(transport.protocol.wrappedProtocol,
                           WebSocketsProtocol)
     self.assertIsInstance(transport.protocol.wrappedProtocol._receiver,
                           SavingEchoReceiver)
Exemple #8
0
    def test_disorderlyShutdown(self):
        """
        If a L{TLSMemoryBIOProtocol} loses its connection unexpectedly, this is
        reported to the application.
        """
        clientConnectionLost = Deferred()
        clientFactory = ClientFactory()
        clientFactory.protocol = (
            lambda: ConnectionLostNotifyingProtocol(clientConnectionLost))

        clientContextFactory = HandshakeCallbackContextFactory()
        wrapperFactory = TLSMemoryBIOFactory(clientContextFactory, True,
                                             clientFactory)
        sslClientProtocol = wrapperFactory.buildProtocol(None)

        # Client speaks first, so the server can be dumb.
        serverProtocol = Protocol()

        connectionDeferred = loopbackAsync(serverProtocol, sslClientProtocol)

        # Now destroy the connection.
        serverProtocol.transport.loseConnection()

        # And when the connection completely dies, check the reason.
        def cbDisconnected(clientProtocol):
            clientProtocol.lostConnectionReason.trap(Error)

        clientConnectionLost.addCallback(cbDisconnected)
        return clientConnectionLost
Exemple #9
0
 def request_shell(self, data):
     protocol = Protocol()
     transport = SSHSessionProcessProtocol(self)
     protocol.makeConnection(transport)
     transport.makeConnection(wrapProtocol(protocol))
     self.client = transport
     return True
Exemple #10
0
 def cbConnect(self, rc, data, evt):
     if rc:
         rc = connectExErrors.get(rc, rc)
         self.failIfNotConnected(
             error.getConnectError(
                 (rc, errno.errorcode.get(rc, "Unknown error"))))
     else:
         self.socket.setsockopt(
             socket.SOL_SOCKET,
             SO_UPDATE_CONNECT_CONTEXT,
             struct.pack("P", self.socket.fileno()),
         )
         self.protocol = self.connector.buildProtocol(self.getPeer())
         self.connected = True
         logPrefix = self._getLogPrefix(self.protocol)
         self.logstr = logPrefix + ",client"
         if self.protocol is None:
             # Factory.buildProtocol is allowed to return None.  In that
             # case, make up a protocol to satisfy the rest of the
             # implementation; connectionLost is going to be called on
             # something, for example.  This is easier than adding special
             # case support for a None protocol throughout the rest of the
             # transport implementation.
             self.protocol = Protocol()
             # But dispose of the connection quickly.
             self.loseConnection()
         else:
             self.protocol.makeConnection(self)
             self.startReading()
Exemple #11
0
 def test_interfaces(self):
     """
     L{Protocol} instances provide L{IProtocol} and L{ILoggingContext}.
     """
     proto = Protocol()
     self.assertTrue(verifyObject(IProtocol, proto))
     self.assertTrue(verifyObject(ILoggingContext, proto))
Exemple #12
0
    def test_renderIProtocol(self):
        """
        If the protocol returned by C{lookupProtocol} isn't a
        C{WebSocketsProtocol}, L{WebSocketsResource} wraps it automatically
        with L{WebSocketsProtocolWrapper}.
        """
        def lookupProtocol(names, otherRequest):
            return AccumulatingProtocol(), None

        self.resource = WebSocketsResource(lookupProtocol)

        request = DummyRequest(b"/")
        request.requestHeaders = Headers({
            b"user-agent": [b"user-agent"],
            b"host": [b"host"],
        })
        transport = StringTransportWithDisconnection()
        transport.protocol = Protocol()
        request.transport = transport
        self.update_headers(request,
                            headers={
                                b"upgrade": b"Websocket",
                                b"connection": b"Upgrade",
                                b"sec-websocket-key": b"secure",
                                b"sec-websocket-version": b"13"
                            })
        result = self.resource.render(request)
        self.assertEqual(NOT_DONE_YET, result)
        self.assertIsInstance(transport.protocol, WebSocketsProtocolWrapper)
        self.assertIsInstance(transport.protocol.wrappedProtocol,
                              AccumulatingProtocol)
Exemple #13
0
def build_protocol():
    """
    :return: ``Protocol`` hooked up to transport.
    """
    p = Protocol()
    p.makeConnection(StringTransport())
    return p
Exemple #14
0
 def test_render(self):
     """
     When rendering a request, L{WebSocketsResource} uses the
     C{Sec-WebSocket-Key} header to generate a C{Sec-WebSocket-Accept}
     value. It creates a L{WebSocketsProtocol} instance connected to the
     protocol provided by the user factory.
     """
     request = DummyRequest("/")
     request.requestHeaders = Headers()
     transport = StringTransportWithDisconnection()
     transport.protocol = Protocol()
     request.transport = transport
     request.headers.update({
         "upgrade": "Websocket",
         "connection": "Upgrade",
         "sec-websocket-key": "secure",
         "sec-websocket-version": "13"
     })
     result = self.resource.render(request)
     self.assertEqual(NOT_DONE_YET, result)
     self.assertEqual(
         {
             "connection": "Upgrade",
             "upgrade": "WebSocket",
             "sec-websocket-accept": "oYBv54i42V5dw6KnZqOFroecUTc="
         }, request.outgoingHeaders)
     self.assertEqual([""], request.written)
     self.assertEqual(101, request.responseCode)
     self.assertIdentical(None, request.transport)
     self.assertIsInstance(transport.protocol._receiver, SavingEchoReceiver)
Exemple #15
0
    def _connectDone(self):
        """
        This is a hook for when a connection attempt has succeeded.

        Here, we build the protocol from the
        L{twisted.internet.protocol.ClientFactory} that was passed in, compute
        a log string, begin reading so as to send traffic to the newly built
        protocol, and finally hook up the protocol itself.

        This hook is overridden by L{ssl.Client} to initiate the TLS protocol.
        """
        self.protocol = self.connector.buildProtocol(self.getPeer())
        self.connected = 1
        logPrefix = self._getLogPrefix(self.protocol)
        self.logstr = "%s,client" % logPrefix
        if self.protocol is None:
            # Factory.buildProtocol is allowed to return None.  In that case,
            # make up a protocol to satisfy the rest of the implementation;
            # connectionLost is going to be called on something, for example.
            # This is easier than adding special case support for a None
            # protocol throughout the rest of the transport implementation.
            self.protocol = Protocol()
            # But dispose of the connection quickly.
            self.loseConnection()
        else:
            self.startReading()
            self.protocol.makeConnection(self)
 def setUp(self):
     """
     Create a L{conncache.ConnectionCache}, endpoint and protocol to test
     against.
     """
     self.cache = conncache.ConnectionCache()
     self.endpoint = FakeEndpoint()
     self.protocol = Protocol()
 def test_unregisterProtocol_before_stopFactory(self):
     """Connections can go away before stopFactory occurs without causing
     errors.
     """
     ctf = gracefulshutdown.ConnTrackingFactoryWrapper(Factory())
     p = Protocol()
     ctf.registerProtocol(p)
     ctf.unregisterProtocol(p)  # No error raised.
Exemple #18
0
 def test_loseConnectionCodeAndReason(self):
     """
     L{WebSocketsTransport.loseConnection} accepts a code and a reason which
     are used to build the closing frame.
     """
     transport = StringTransportWithDisconnection()
     transport.protocol = Protocol()
     webSocketsTranport = WebSocketsTransport(transport)
     webSocketsTranport.loseConnection(STATUSES.GOING_AWAY, b"Going away")
     self.assertEqual(b"\x88\x0c\x03\xe9Going away", transport.value())
Exemple #19
0
    def setUp(self):
        # Re-usable protocol and reactor
        self.protocol = Protocol()
        self.reactor = DoNothing()

        self.directory = tempfile.mkdtemp()
        self.path = os.path.join(self.directory, 'fake_serial')

        data = b'1234'
        with open(self.path, 'wb') as f:
            f.write(data)
 def __init__(self, message_object, factory):
     """
     :param factory: instance of factory creating this protocol class
     :param message_object: an instance of the SpokenMessages class
                             (must have speak(), listen(), follow_up())
     implemented
     """
     Protocol().__init__()
     self.factory = factory
     self.message_object = message_object
     assert (isinstance(self.message_object, SpokenMessages))
Exemple #21
0
 def test_protocolToConsumer(self):
     """
     L{IProtocol} providers can be adapted to L{IConsumer} providers using
     L{ProtocolToConsumerAdapter}.
     """
     result = []
     p = Protocol()
     p.dataReceived = result.append
     consumer = IConsumer(p)
     consumer.write(b"hello")
     self.assertEqual(result, [b"hello"])
     self.assertIsInstance(consumer, ProtocolToConsumerAdapter)
Exemple #22
0
 def test_startService(self):
     """
     L{StandardIOService.startService} connects a protocol to a standard io
     transport.
     """
     # This sucks.  StandardIO sucks.  APIs should be testable.
     L = []
     self.patch(process, 'StandardIO', L.append)
     proto = Protocol()
     service = process.StandardIOService(proto)
     service.startService()
     self.assertEqual(L, [proto])
Exemple #23
0
    def test_loseConnectionAfterHandshake(self):
        """
        L{TLSMemoryBIOProtocol.loseConnection} sends a TLS close alert and
        shuts down the underlying connection.
        """
        clientConnectionLost = Deferred()
        clientFactory = ClientFactory()
        clientFactory.protocol = (
            lambda: ConnectionLostNotifyingProtocol(clientConnectionLost))

        clientContextFactory, handshakeDeferred = (
            HandshakeCallbackContextFactory.factoryAndDeferred())
        wrapperFactory = TLSMemoryBIOFactory(clientContextFactory, True,
                                             clientFactory)
        sslClientProtocol = wrapperFactory.buildProtocol(None)

        serverProtocol = Protocol()
        serverFactory = ServerFactory()
        serverFactory.protocol = lambda: serverProtocol

        serverContextFactory = DefaultOpenSSLContextFactory(certPath, certPath)
        wrapperFactory = TLSMemoryBIOFactory(serverContextFactory, False,
                                             serverFactory)
        sslServerProtocol = wrapperFactory.buildProtocol(None)

        connectionDeferred = loopbackAsync(sslServerProtocol,
                                           sslClientProtocol)

        # Wait for the handshake before dropping the connection.
        def cbHandshake(ignored):
            serverProtocol.transport.loseConnection()

            # Now wait for the client to notice.
            return clientConnectionLost

        handshakeDeferred.addCallback(cbHandshake)

        # Wait for the connection to end, then make sure the client was
        # notified of a handshake failure.
        def cbConnectionDone(clientProtocol):
            clientProtocol.lostConnectionReason.trap(ConnectionDone)

            # The server should have closed its underlying transport, in
            # addition to whatever it did to shut down the TLS layer.
            self.assertTrue(serverProtocol.transport.q.disconnect)

            # The client should also have closed its underlying transport once
            # it saw the server shut down the TLS layer, so as to avoid relying
            # on the server to close the underlying connection.
            self.assertTrue(clientProtocol.transport.q.disconnect)

        handshakeDeferred.addCallback(cbConnectionDone)
        return handshakeDeferred
    def test_data_cancels_timeout(self):
        """
        When data is received, the timeout is canceled
        """
        clock = Clock()
        protocol = HangCheckProtocol(Protocol(), reactor=clock)
        transport = StringTransport()

        transport.protocol = protocol
        protocol.makeConnection(transport)
        protocol.dataReceived('some-data')
        assert_clock_idle(self, clock)
 def reconnector(self, onion):
     protocol = Protocol()
     protocol.onion = onion
     protocol.connectionLost = lambda failure: self.handleLostConnection(
         failure, onion)
     tor_endpoint = clientFromString(self.reactor,
                                     "tor:%s.onion:8060" % onion)
     self.onion_pending_map[onion] = connectProtocol(tor_endpoint, protocol)
     self.onion_pending_map[onion].addCallback(
         lambda protocol: self.connection_ready(onion, protocol))
     self.onion_pending_map[onion].addErrback(
         lambda failure: self.connectFail(failure, onion))
Exemple #26
0
 def test_loseConnection(self):
     """
     L{WebSocketsTransport.loseConnection} sends a close frame and closes
     the transport afterwards.
     """
     transport = StringTransportWithDisconnection()
     transport.protocol = Protocol()
     webSocketsTranport = WebSocketsTransport(transport)
     webSocketsTranport.loseConnection()
     self.assertFalse(transport.connected)
     self.assertEqual(b"\x88\x02\x03\xe8", transport.value())
     # We can call loseConnection again without side effects
     webSocketsTranport.loseConnection()
Exemple #27
0
    def test_spawnProcess(self):
        """
        The process protocol for a spawned process is connected to a
        transport and appended onto the provided C{workers} list, and
        the reactor's C{spawnCount} increased.
        """
        self.assertFalse(self.reactor.spawnCount)

        proto = Protocol()
        for count in [1, 2]:
            self.reactor.spawnProcess(proto, sys.executable, args=[sys.executable])
            self.assertTrue(proto.transport)
            self.assertEqual(self.workers, [proto] * count)
            self.assertEqual(self.reactor.spawnCount, count)
Exemple #28
0
    def test_renderProtocol(self):
        """
        If protocols are specified via the C{Sec-WebSocket-Protocol} header,
        L{WebSocketsResource} passes them to its C{lookupProtocol} argument,
        which can decide which protocol to return, and which is accepted.
        """

        def lookupProtocol(names, otherRequest):
            self.assertEqual([b"foo", b"bar"], names)
            self.assertIs(request, otherRequest)
            return self.echoProtocol, b"bar"

        self.resource = WebSocketsResource(lookupProtocol)

        request = DummyRequest(b"/")
        request.requestHeaders = Headers(
            {
                b"sec-websocket-protocol": [b"foo", b"bar"],
                b"user-agent": [b"user-agent"],
                b"host": [b"host"],
            }
        )
        transport = StringTransportWithDisconnection()
        transport.protocol = Protocol()
        request.transport = transport
        self.update_headers(
            request,
            headers={
                b"upgrade": b"Websocket",
                b"connection": b"Upgrade",
                b"sec-websocket-key": b"secure",
                b"sec-websocket-version": b"13",
            },
        )
        result = self.resource.render(request)
        self.assertEqual(NOT_DONE_YET, result)
        self.assertEqual(
            {
                b"Connection": [b"Upgrade"],
                b"Upgrade": [b"WebSocket"],
                b"Sec-Websocket-Protocol": [b"bar"],
                b"Sec-Websocket-Accept": [b"oYBv54i42V5dw6KnZqOFroecUTc="],
            },
            {
                name: value
                for name, value in request.responseHeaders.getAllRawHeaders()
            },
        )
        self.assertEqual([b""], request.written)
        self.assertEqual(101, request.responseCode)
    def test_transport(self):
        """
        The transport passed to the underlying protocol is
        the underlying transport.
        """
        clock = Clock()
        wrapped_protocol = Protocol()
        protocol = HangCheckProtocol(wrapped_protocol, reactor=clock)
        transport = StringTransport()

        transport.protocol = protocol
        protocol.makeConnection(transport)

        self.assertIdentical(wrapped_protocol.transport, transport)
    def test_allConnectionsGone_when_more_than_one_connection(self):
        """
        When there are two connections allConnectionsGone fires when both
        connections go away.
        """
        ctf = gracefulshutdown.ConnTrackingFactoryWrapper(Factory())
        # Make two connection
        p1 = Protocol()
        p2 = Protocol()
        ctf.registerProtocol(p1)
        ctf.registerProtocol(p2)
        ctf.stopFactory()
        self.was_fired = False

        def cb(ignored):
            self.was_fired = True

        ctf.allConnectionsGone.addCallback(cb)
        self.assertFalse(self.was_fired)
        ctf.unregisterProtocol(p1)
        self.assertFalse(self.was_fired)
        ctf.unregisterProtocol(p2)
        self.assertTrue(self.was_fired)