def _testDataForward(self, data, method="GET", body=""): """ Build a fake proxy connection, and send C{data} over it, checking that it's forwarded to the originating request. """ # Connect everything clientTransport = StringTransportWithDisconnection() serverTransport = StringTransportWithDisconnection() channel = DummyChannel(serverTransport) parent = DummyParent(channel) serverTransport.protocol = channel client = ProxyClient(method, '/foo', 'HTTP/1.0', {"accept": "text/html"}, body, parent) clientTransport.protocol = client client.makeConnection(clientTransport) # Check data sent self.assertEquals(clientTransport.value(), "%s /foo HTTP/1.0\r\n" "connection: close\r\n" "accept: text/html\r\n\r\n%s" % (method, body)) # Fake an answer client.dataReceived(data) # Check that the data has been forwarded self.assertEquals(serverTransport.value(), data) clientTransport.loseConnection() self.assertIsInstance(channel.lostReason, ConnectionDone)
def _testDataForward(self, data, method="GET", body=""): """ Build a fake proxy connection, and send C{data} over it, checking that it's forwarded to the originating request. """ # Connect everything clientTransport = StringTransportWithDisconnection() serverTransport = StringTransportWithDisconnection() channel = DummyChannel(serverTransport) parent = DummyParent(channel) serverTransport.protocol = channel client = ProxyClient(method, '/foo', 'HTTP/1.0', {"accept": "text/html"}, body, parent) clientTransport.protocol = client client.makeConnection(clientTransport) # Check data sent self.assertEquals( clientTransport.value(), "%s /foo HTTP/1.0\r\n" "connection: close\r\n" "accept: text/html\r\n\r\n%s" % (method, body)) # Fake an answer client.dataReceived(data) # Check that the data has been forwarded self.assertEquals(serverTransport.value(), data) clientTransport.loseConnection() self.assertIsInstance(channel.lostReason, ConnectionDone)
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)
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)
def testThingsGetLogged(self): wrappedFactory = Server() wrappedFactory.protocol = WriteSequenceEchoProtocol t = StringTransportWithDisconnection() f = TestLoggingFactory(wrappedFactory, 'test') p = f.buildProtocol(('1.2.3.4', 5678)) t.protocol = p p.makeConnection(t) v = f.openFile.getvalue() self.failUnless('*' in v, "* not found in %r" % (v,)) self.failIf(t.value()) p.dataReceived('here are some bytes') v = f.openFile.getvalue() self.assertNotEqual(-1, v.find("C 1: 'here are some bytes'"), "Expected client string not found in %r" % (v,)) self.assertNotEqual(-1, v.find("S 1: 'here are some bytes'"), "Expected server string not found in %r" % (v,)) self.assertEquals(t.value(), 'here are some bytes') t.clear() p.dataReceived('prepare for vector! to the extreme') v = f.openFile.getvalue() self.assertNotEqual(-1, v.find("SV 1: ['prepare for vector! to the extreme']"), "Expected server string not found in %r" % (v,)) self.assertEquals(t.value(), 'prepare for vector! to the extreme') p.loseConnection() v = f.openFile.getvalue() self.assertNotEqual(-1, v.find('ConnectionDone'), "Connection done notification not found in %r" % (v,))
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)
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)
def test_rawsocket_with_factory(self): """ Speaking RawSocket when the connection is made will make UniSocket create a new RawSocket protocol and send the data to it. """ t = StringTransport() class MyFakeRawSocket(Protocol): """ A fake RawSocket factory which just echos data back. """ def dataReceived(self, data): self.transport.write(data) fake_rawsocket = Factory.forProtocol(MyFakeRawSocket) f = UniSocketServerFactory(rawsocket_factory=fake_rawsocket) p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'\x7F0000000') p.dataReceived(b'moredata') self.assertTrue(t.connected) self.assertEqual(t.value(), b'\x7F0000000moredata')
def test_websocket_with_map(self): """ Speaking WebSocket when the connection is made will make UniSocket create a new WebSocket protocol and send the data to it. """ t = StringTransport() class MyFakeWebSocket(Protocol): """ A fake WebSocket factory which just echos data back. """ def dataReceived(self, data): self.transport.write(data) fake_websocket = Factory.forProtocol(MyFakeWebSocket) websocket_map = OrderedDict({u"baz": None}) websocket_map["ws"] = fake_websocket f = UniSocketServerFactory(websocket_factory_map=websocket_map) p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'GET /ws HTTP/1.1\r\nConnection: close\r\n\r\n') self.assertTrue(t.connected) self.assertEqual(t.value(), b'GET /ws HTTP/1.1\r\nConnection: close\r\n\r\n')
def test_web_with_factory(self): """ Speaking HTTP will pass it down to the HTTP factory. """ t = StringTransport() class MyResource(Resource): isLeaf = True def render_GET(self, request): return b"hi!" r = MyResource() s = Site(r) f = UniSocketServerFactory(web_factory=s) p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'GET / HTTP/1.1\r\nConnection: close\r\n\r\n') self.assertFalse(t.connected) self.assertIn(b"hi!", t.value())
def test_thingsGetLogged(self): """ Check the output produced by L{policies.TrafficLoggingFactory}. """ wrappedFactory = Server() wrappedFactory.protocol = WriteSequenceEchoProtocol t = StringTransportWithDisconnection() f = TestLoggingFactory(wrappedFactory, "test") p = f.buildProtocol(("1.2.3.4", 5678)) t.protocol = p p.makeConnection(t) v = f.openFile.getvalue() self.assertIn("*", v) self.assertFalse(t.value()) p.dataReceived(b"here are some bytes") v = f.openFile.getvalue() self.assertIn("C 1: {!r}".format(b"here are some bytes"), v) self.assertIn("S 1: {!r}".format(b"here are some bytes"), v) self.assertEqual(t.value(), b"here are some bytes") t.clear() p.dataReceived(b"prepare for vector! to the extreme") v = f.openFile.getvalue() self.assertIn("SV 1: {!r}".format([b"prepare for vector! to the extreme"]), v) self.assertEqual(t.value(), b"prepare for vector! to the extreme") p.loseConnection() v = f.openFile.getvalue() self.assertIn("ConnectionDone", v)
def test_writeLimit(self): """ Check the writeLimit parameter: write data, and check for the pause status. """ server = Server() tServer = TestableThrottlingFactory(task.Clock(), server, writeLimit=10) port = tServer.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 0)) tr = StringTransportWithDisconnection() tr.protocol = port port.makeConnection(tr) port.producer = port.wrappedProtocol port.dataReceived("0123456789") port.dataReceived("abcdefghij") self.assertEqual(tr.value(), "0123456789abcdefghij") self.assertEqual(tServer.writtenThisSecond, 20) self.assertFalse(port.wrappedProtocol.paused) # at this point server should've written 20 bytes, 10 bytes # above the limit so writing should be paused around 1 second # from 'now', and resumed a second after that tServer.clock.advance(1.05) self.assertEqual(tServer.writtenThisSecond, 0) self.assertTrue(port.wrappedProtocol.paused) tServer.clock.advance(1.05) self.assertEqual(tServer.writtenThisSecond, 0) self.assertFalse(port.wrappedProtocol.paused)
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(["foo", "bar"], names) self.assertIdentical(request, otherRequest) return self.echoProtocol, "bar" self.resource = WebSocketsResource(lookupProtocol) request = DummyRequest("/") request.requestHeaders = Headers( {"sec-websocket-protocol": ["foo", "bar"]}) 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-protocol": "bar", "sec-websocket-accept": "oYBv54i42V5dw6KnZqOFroecUTc="}, request.outgoingHeaders) self.assertEqual([""], request.written) self.assertEqual(101, request.responseCode)
def test_connectToNode(self): """ L{OneShotPortMapperFactory.connectToNode} should return a L{Deferred} that will be called back with the instance of the protocol connected to the erlang node. """ clientFactory = DummyClientFactory() self.factory.nodeFactoryClass = lambda a, b, c: clientFactory d = self.factory.connectToNode("egg@spam") transport = StringTransportWithDisconnection() proto = self.factory.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEqual(transport.value(), "\x00\x04zegg") self.assertEqual( self.factory.connect, [("127.0.0.1", 4369, self.factory)]) proto.dataReceived( "w\x00\x00\x09M\x01\x00\x05\x00\x05\x00\x03bar\x00") clientProto = object() clientFactory._connectDeferred.callback(clientProto) self.assertEqual( self.factory.connect, [("127.0.0.1", 4369, self.factory), ("127.0.0.1", 9, clientFactory)]) return d.addCallback(self.assertIdentical, clientProto)
def test_writeLimit(self): """ Check the writeLimit parameter: write data, and check for the pause status. """ server = Server() tServer = TestableThrottlingFactory(task.Clock(), server, writeLimit=10) port = tServer.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 0)) tr = StringTransportWithDisconnection() tr.protocol = port port.makeConnection(tr) port.producer = port.wrappedProtocol port.dataReceived(b"0123456789") port.dataReceived(b"abcdefghij") self.assertEqual(tr.value(), b"0123456789abcdefghij") self.assertEqual(tServer.writtenThisSecond, 20) self.assertFalse(port.wrappedProtocol.paused) # at this point server should've written 20 bytes, 10 bytes # above the limit so writing should be paused around 1 second # from 'now', and resumed a second after that tServer.clock.advance(1.05) self.assertEqual(tServer.writtenThisSecond, 0) self.assertTrue(port.wrappedProtocol.paused) tServer.clock.advance(1.05) self.assertEqual(tServer.writtenThisSecond, 0) self.assertFalse(port.wrappedProtocol.paused)
def test_thingsGetLogged(self): """ Check the output produced by L{policies.TrafficLoggingFactory}. """ wrappedFactory = Server() wrappedFactory.protocol = WriteSequenceEchoProtocol t = StringTransportWithDisconnection() f = TestLoggingFactory(wrappedFactory, 'test') p = f.buildProtocol(('1.2.3.4', 5678)) t.protocol = p p.makeConnection(t) v = f.openFile.getvalue() self.failUnless('*' in v, "* not found in %r" % (v,)) self.failIf(t.value()) p.dataReceived('here are some bytes') v = f.openFile.getvalue() self.assertIn("C 1: 'here are some bytes'", v) self.assertIn("S 1: 'here are some bytes'", v) self.assertEqual(t.value(), 'here are some bytes') t.clear() p.dataReceived('prepare for vector! to the extreme') v = f.openFile.getvalue() self.assertIn("SV 1: ['prepare for vector! to the extreme']", v) self.assertEqual(t.value(), 'prepare for vector! to the extreme') p.loseConnection() v = f.openFile.getvalue() self.assertIn('ConnectionDone', v)
def test_thingsGetLogged(self): """ Check the output produced by L{policies.TrafficLoggingFactory}. """ wrappedFactory = Server() wrappedFactory.protocol = WriteSequenceEchoProtocol t = StringTransportWithDisconnection() f = TestLoggingFactory(wrappedFactory, 'test') p = f.buildProtocol(('1.2.3.4', 5678)) t.protocol = p p.makeConnection(t) v = f.openFile.getvalue() self.assertIn('*', v) self.assertFalse(t.value()) p.dataReceived(b'here are some bytes') v = f.openFile.getvalue() self.assertIn("C 1: %r" % (b'here are some bytes',), v) self.assertIn("S 1: %r" % (b'here are some bytes',), v) self.assertEqual(t.value(), b'here are some bytes') t.clear() p.dataReceived(b'prepare for vector! to the extreme') v = f.openFile.getvalue() self.assertIn("SV 1: %r" % ([b'prepare for vector! to the extreme'],), v) self.assertEqual(t.value(), b'prepare for vector! to the extreme') p.loseConnection() v = f.openFile.getvalue() self.assertIn('ConnectionDone', v)
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("/") 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.assertIsInstance(transport.protocol, WebSocketsProtocolWrapper) self.assertIsInstance(transport.protocol.wrappedProtocol, AccumulatingProtocol)
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)
def test_getNodeConnection(self): """ L{Process._getNodeConnection}, if no connection is established, as a connection to a L{OneShotPortMapperFactory}. Once it gets a connection it sets the calls handler to the client factory to the process handler. """ d = self.process._getNodeConnection("egg@spam") epmd = self.process.oneShotEpmds["spam"] transport = StringTransportWithDisconnection() proto = epmd.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEqual(transport.value(), "\x00\x04zegg") self.assertEqual(epmd.connect, [("spam", 4369, epmd)]) proto.dataReceived( "w\x00\x00\x09M\x01\x00\x05\x00\x05\x00\x03bar\x00") [factory] = epmd.factories self.assertEqual( epmd.factoriesArgs, [("foo@bar", "test_cookie", epmd.onConnectionLost)]) clientProto = TestableNodeProtocol() clientProto.factory = factory factory._connectDeferred.callback(clientProto) def check(proto): self.assertIdentical(proto, clientProto) self.assertIdentical(factory.handler, self.process.handler) return d.addCallback(check)
def _serverSetup(self): wrappedFactory = protocol.ServerFactory() wrappedFactory.protocol = SimpleProtocol factory = policies.TimeoutFactory(wrappedFactory, 3) proto = factory.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 12345)) transport = StringTransportWithDisconnection() transport.protocol = proto proto.makeConnection(transport) return factory, proto, transport
def connect_transport(protocol, factory=None): """ Connect a StringTransport to a client protocol. """ if factory is None: factory = ClientFactory() transport = StringTransportWithDisconnection() protocol.makeConnection(transport) transport.protocol = protocol protocol.factory = factory return transport
def connect(self, protocolFactory): string_transport = StringTransportWithDisconnection() protocol = protocolFactory.buildProtocol(None) protocol.makeConnection(string_transport) string_transport.protocol = protocol self.connect_callback(protocol) d = Deferred() d.callback(protocol) return d
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())
def gen_prot(self, app): from spyne.server.twisted.msgpack import TwistedMessagePackProtocol from twisted.test.proto_helpers import StringTransportWithDisconnection prot = TwistedMessagePackProtocol(app) transport = StringTransportWithDisconnection() prot.makeConnection(transport) transport.protocol = prot return prot
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, "Going away") self.assertEqual("\x88\x0c\x03\xe9Going away", transport.value())
def _serverSetup(self): # Create a server factory, get a protocol from it, connect it to a # transport, and return all three. wrappedFactory = protocol.ServerFactory() wrappedFactory.protocol = SimpleProtocol factory = policies.TimeoutFactory(wrappedFactory, 3) proto = factory.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 12345)) transport = StringTransportWithDisconnection() transport.protocol = proto proto.makeConnection(transport) return factory, proto, transport
def test_connection(self): """ On connection, the EPMD client should send an ALIVE2 request. """ self.factory.nodePortNumber = 1234 transport = StringTransportWithDisconnection() proto = self.factory.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEquals(transport.value(), "\x00\x10x\x04\xd2H\x00\x00\x05\x00\x05\x00\x03foo\x00\x00")
def test_invalidHeaderDisconnects(self): """ Test if invalid headers result in connectionLost events. """ factory = HAProxyWrappingFactory(Factory.forProtocol(StaticProtocol)) proto = factory.buildProtocol(address.IPv4Address("TCP", b"127.1.1.1", 8080)) transport = StringTransportWithDisconnection() transport.protocol = proto proto.makeConnection(transport) proto.dataReceived(b"NOTPROXY anything can go here\r\n") self.assertFalse(transport.connected)
def connectProxy(self, proxyClient): """ Connect a proxy client to a L{StringTransportWithDisconnection}. @param proxyClient: A L{ProxyClient}. @return: The L{StringTransportWithDisconnection}. """ clientTransport = StringTransportWithDisconnection() clientTransport.protocol = proxyClient proxyClient.makeConnection(clientTransport) return clientTransport
def _testDataForward(self, code, message, headers, body, method="GET", requestBody="", loseConnection=True): """ Build a fake proxy connection, and send C{data} over it, checking that it's forwarded to the originating request. """ request = DummyRequest(['foo']) # Connect a proxy client to a fake transport. clientTransport = StringTransportWithDisconnection() client = ProxyClient(method, '/foo', 'HTTP/1.0', {"accept": "text/html"}, requestBody, request) clientTransport.protocol = client client.makeConnection(clientTransport) # Check data sent self.assertEquals( clientTransport.value(), "%s /foo HTTP/1.0\r\n" "connection: close\r\n" "accept: text/html\r\n\r\n%s" % (method, requestBody)) # Fake an answer client.dataReceived("HTTP/1.0 %d %s\r\n" % (code, message)) for (header, values) in headers: for value in values: client.dataReceived("%s: %s\r\n" % (header, value)) client.dataReceived("\r\n" + body) # Check that the response data has been forwarded back to the original # requester. self.assertEquals(request.responseCode, code) self.assertEquals(request.responseMessage, message) receivedHeaders = list(request.responseHeaders.getAllRawHeaders()) receivedHeaders.sort() expectedHeaders = headers[:] expectedHeaders.sort() self.assertEquals(receivedHeaders, expectedHeaders) self.assertEquals(''.join(request.written), body) # Check that when the response is done, the request is finished. if loseConnection: clientTransport.loseConnection() # Even if we didn't call loseConnection, the transport should be # disconnected. This lets us not rely on the server to close our # sockets for us. self.assertFalse(clientTransport.connected) self.assertEquals(request.finished, 1)
def test_invalidHeaderDisconnects(self): """ Test if invalid headers result in connectionLost events. """ factory = HAProxyWrappingFactory(Factory.forProtocol(StaticProtocol)) proto = factory.buildProtocol(address.IPv6Address("TCP", b"::1", 8080)) transport = StringTransportWithDisconnection() transport.protocol = proto proto.makeConnection(transport) proto.dataReceived(b"\x00" + self.IPV4HEADER[1:]) self.assertFalse(transport.connected)
def test_invalidHeaderDisconnects(self): """ Test if invalid headers result in connectionLost events. """ factory = HAProxyWrappingFactory(Factory.forProtocol(StaticProtocol)) proto = factory.buildProtocol(address.IPv6Address('TCP', b'::1', 8080), ) transport = StringTransportWithDisconnection() transport.protocol = proto proto.makeConnection(transport) proto.dataReceived(b'\x00' + self.IPV4HEADER[1:]) self.assertFalse(transport.connected)
def test_invalidHeaderDisconnects(self): """ Test if invalid headers result in connectionLost events. """ factory = HAProxyWrappingFactory(Factory.forProtocol(StaticProtocol)) proto = factory.buildProtocol( address.IPv4Address('TCP', b'127.1.1.1', 8080), ) transport = StringTransportWithDisconnection() transport.protocol = proto proto.makeConnection(transport) proto.dataReceived(b'NOTPROXY anything can go here\r\n') self.assertFalse(transport.connected)
def makeTestConnections(client): client.factories = [] transports = [] for addr in client.hosts: factory = MemCacheClientFactory() client.factories.append(factory) proto = factory.buildProtocol(addr, timeOut=None) transport = StringTransportWithDisconnection() transport.protocol = proto proto.makeConnection(transport) transports.append(transport) return transports
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()
def test_invalidPartialHeaderDisconnects(self): """ Test if invalid headers result in connectionLost events. """ factory = HAProxyWrappingFactory(Factory.forProtocol(StaticProtocol)) proto = factory.buildProtocol( address.IPv4Address("TCP", b"127.1.1.1", 8080), ) transport = StringTransportWithDisconnection() transport.protocol = proto proto.makeConnection(transport) proto.dataReceived(b"PROXY TCP4 1.1.1.1\r\n") proto.dataReceived(b"2.2.2.2 8080\r\n") self.assertFalse(transport.connected)
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("\x88\x02\x03\xe8", transport.value()) # We can call loseConnection again without side effects webSocketsTranport.loseConnection()
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_writeSequence(self): """ L{ThrottlingProtocol.writeSequence} is called on the underlying factory. """ server = Server() tServer = TestableThrottlingFactory(task.Clock(), server) protocol = tServer.buildProtocol(address.IPv4Address("TCP", "127.0.0.1", 0)) transport = StringTransportWithDisconnection() transport.protocol = protocol protocol.makeConnection(transport) protocol.writeSequence([b"bytes"] * 4) self.assertEqual(transport.value(), b"bytesbytesbytesbytes") self.assertEqual(tServer.writtenThisSecond, 20)
def test_websocket_mechanics(): """ Shows that we can put our protocol (hey_joe._WayDownSouth) and factory (hey_joe.WebSocketService) together, along with a transport, and properly open a websocket connection. """ transport = StringTransportWithDisconnection() service = hey_joe.WebSocketService("127.0.0.1", 9000) protocol = service.buildProtocol(service._hey_joe_addr) protocol.transport = transport transport.protocol = protocol protocol.connectionMade() data_to_send = b'GET / HTTP/1.1\r\nHost: somewhere_in_the_world:9000\r\nConnection: keep-alive, Upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: F76ObkF/aCKX8WkmAgx2OQ==\r\n\r\n' protocol.dataReceived(data_to_send) assert transport.value().startswith(b'HTTP/1.1 101 Switching Protocols\r\nServer: hendrix')
def test_kill(self): """ L{OneShotPortMapperFactory.kill} should return a L{Deferred} that will be called back when the kill request is complete. """ d = self.factory.kill() transport = StringTransportWithDisconnection() proto = self.factory.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEqual(transport.value(), "\x00\x01k") proto.dataReceived("OK") transport.loseConnection() return d.addCallback(self.assertEqual, "OK")
def test_web_with_no_factory(self): """ Trying to speak HTTP without a factory will drop the connection. """ t = StringTransport() f = UniSocketServerFactory() p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'GET /foo HTTP/1.1\r\n\r\n') self.assertFalse(t.connected)
def test_names(self): """ L{OneShotPortMapperFactory.names} should return a L{Deferred} that will be called back when the names request is complete. """ d = self.factory.names() transport = StringTransportWithDisconnection() proto = self.factory.buildProtocol(("127.0.01", 4369)) proto.makeConnection(transport) transport.protocol = proto self.assertEqual(transport.value(), "\x00\x01n") proto.dataReceived("\x00\x00\x00\x01") proto.dataReceived("name %s at port %s\n" % ("foo", 1234)) transport.loseConnection() return d.addCallback(self.assertEqual, [("foo", 1234)])
def test_writeSequence(self): """ L{ThrottlingProtocol.writeSequence} is called on the underlying factory. """ server = Server() tServer = TestableThrottlingFactory(task.Clock(), server) protocol = tServer.buildProtocol( address.IPv4Address('TCP', '127.0.0.1', 0)) transport = StringTransportWithDisconnection() transport.protocol = protocol protocol.makeConnection(transport) protocol.writeSequence([b'bytes'] * 4) self.assertEqual(transport.value(), b"bytesbytesbytesbytes") self.assertEqual(tServer.writtenThisSecond, 20)
def _testDataForward(self, code, message, headers, body, method="GET", requestBody="", loseConnection=True): """ Build a fake proxy connection, and send C{data} over it, checking that it's forwarded to the originating request. """ request = DummyRequest(['foo']) # Connect a proxy client to a fake transport. clientTransport = StringTransportWithDisconnection() client = ProxyClient(method, '/foo', 'HTTP/1.0', {"accept": "text/html"}, requestBody, request) clientTransport.protocol = client client.makeConnection(clientTransport) # Check data sent self.assertEquals(clientTransport.value(), "%s /foo HTTP/1.0\r\n" "connection: close\r\n" "accept: text/html\r\n\r\n%s" % (method, requestBody)) # Fake an answer client.dataReceived("HTTP/1.0 %d %s\r\n" % (code, message)) for (header, values) in headers: for value in values: client.dataReceived("%s: %s\r\n" % (header, value)) client.dataReceived("\r\n" + body) # Check that the response data has been forwarded back to the original # requester. self.assertEquals(request.responseCode, code) self.assertEquals(request.responseMessage, message) receivedHeaders = list(request.responseHeaders.getAllRawHeaders()) receivedHeaders.sort() expectedHeaders = headers[:] expectedHeaders.sort() self.assertEquals(receivedHeaders, expectedHeaders) self.assertEquals(''.join(request.written), body) # Check that when the response is done, the request is finished. if loseConnection: clientTransport.loseConnection() # Even if we didn't call loseConnection, the transport should be # disconnected. This lets us not rely on the server to close our # sockets for us. self.assertFalse(clientTransport.connected) self.assertEquals(request.finished, 1)
def test_invalid_status_line(self): """ Not speaking RawSocket or MQTT but also not speaking a type of HTTP will cause the connection to be dropped. """ t = StringTransport() f = UniSocketServerFactory() p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'this is not HTTP\r\n\r\n') self.assertFalse(t.connected)
def test_breakReferenceCycle(self): """ L{policies.ProtocolWrapper.connectionLost} sets C{wrappedProtocol} to C{None} in order to break reference cycle between wrapper and wrapped protocols. :return: """ wrapper = policies.ProtocolWrapper(policies.WrappingFactory(Server()), protocol.Protocol()) transport = StringTransportWithDisconnection() transport.protocol = wrapper wrapper.makeConnection(transport) self.assertIsNotNone(wrapper.wrappedProtocol) transport.loseConnection() self.assertIsNone(wrapper.wrappedProtocol)
def test_rawsocket_with_no_factory(self): """ Trying to speak RawSocket with no RawSocket factory configured will drop the connection. """ t = StringTransport() f = UniSocketServerFactory() p = f.buildProtocol(None) p.makeConnection(t) t.protocol = p self.assertTrue(t.connected) p.dataReceived(b'\x7F0000000') self.assertFalse(t.connected)