def connectSSL(host, port, factory, repositoryView, protocol='sslv23', timeout=30, bindAddress=None, reactor=twisted.internet.reactor): """ A convenience function to start an SSL/TLS connection using Twisted. See IReactorSSL interface in Twisted. """ if __debug__: log.debug('connectSSL(host=%s, port=%d)' % (host, port)) wrappingFactory = policies.WrappingFactory(factory) wrappingFactory.protocol = lambda factory, wrappedProtocol: \ TwistedProtocolWrapper(repositoryView, protocol, factory, wrappedProtocol, startPassThrough=0, client=1) return reactor.connectTCP(host, port, wrappingFactory, timeout, bindAddress)
def test_transportInterfaces(self): """ The transport wrapper passed to the wrapped protocol's C{makeConnection} provides the same interfaces as are provided by the original transport. """ class IStubTransport(Interface): pass @implementer(IStubTransport) class StubTransport: pass # Looking up what ProtocolWrapper implements also mutates the class. # It adds __implemented__ and __providedBy__ attributes to it. These # prevent __getattr__ from causing the IStubTransport.providedBy call # below from returning True. If, by accident, nothing else causes # these attributes to be added to ProtocolWrapper, the test will pass, # but the interface will only be provided until something does trigger # their addition. So we just trigger it right now to be sure. implementedBy(policies.ProtocolWrapper) proto = protocol.Protocol() wrapper = policies.ProtocolWrapper(policies.WrappingFactory(None), proto) wrapper.makeConnection(StubTransport()) self.assertTrue(IStubTransport.providedBy(proto.transport))
def connectTCP(host, port, factory, timeout=30, bindAddress=None, reactor=twisted.internet.reactor, postConnectionCheck=Checker()): # type: (str, int, object, int, Optional[util.AddrType], object, Callable) -> object """ A convenience function to start a TCP connection using Twisted. NOTE: You must call startTLS(ctx) to go into SSL/TLS mode. See IReactorTCP interface in Twisted. """ wrappingFactory = policies.WrappingFactory(factory) wrappingFactory.protocol = lambda factory, wrappedProtocol: \ TLSProtocolWrapper(factory, wrappedProtocol, startPassThrough=1, client=1, contextFactory=None, postConnectionCheck=postConnectionCheck) return reactor.connectTCP(host, port, wrappingFactory, timeout, bindAddress)
def connectTCP(host, port, factory, repositoryView, protocol='tlsv1', timeout=30, bindAddress=None, reactor=twisted.internet.reactor, postConnectionCheck=Checker.Checker()): """ A convenience function to start a TCP connection using Twisted. NOTE: You must call startTLS(ctx) to go into SSL/TLS mode. See IReactorSSL interface in Twisted. """ log.debug('connectSSL(host=%s, port=%d)' % (host, port)) wrappingFactory = policies.WrappingFactory(factory) wrappingFactory.protocol = lambda factory, wrappedProtocol: \ TwistedProtocolWrapper(repositoryView, protocol, factory, wrappedProtocol, startPassThrough=1, client=1, postConnectionCheck=postConnectionCheck) return reactor.connectTCP(host, port, wrappingFactory, timeout, bindAddress)
def test_factoryLogPrefix(self): """ L{WrappingFactory.logPrefix} is customized to mention both the original factory and the wrapping factory. """ server = Server() factory = policies.WrappingFactory(server) self.assertEqual("Server (WrappingFactory)", factory.logPrefix())
def test_protocolFactoryAttribute(self): """ Make sure protocol.factory is the wrapped factory, not the wrapping factory. """ f = Server() wf = policies.WrappingFactory(f) p = wf.buildProtocol(address.IPv4Address('TCP', '127.0.0.1', 35)) self.assertIs(p.wrappedProtocol.factory, f)
def setUp(self): name = self.mktemp() os.mkdir(name) FilePath(name).child("file").setContent("0123456789") r = static.File(name) self.site = server.Site(r, timeout=None) self.wrapper = policies.WrappingFactory(self.site) self.port = self._listen(self.wrapper) self.portno = self.port.getHost().port
def test_protocolLogPrefix(self): """ L{ProtocolWrapper.logPrefix} is customized to mention both the original protocol and the wrapper. """ server = Server() factory = policies.WrappingFactory(server) protocol = factory.buildProtocol(address.IPv4Address("TCP", "127.0.0.1", 35)) self.assertEqual("EchoProtocol (ProtocolWrapper)", protocol.logPrefix())
def _getWrapper(self): """ Return L{policies.ProtocolWrapper} that has been connected to a L{StringTransport}. """ wrapper = policies.ProtocolWrapper(policies.WrappingFactory(Server()), protocol.Protocol()) transport = StringTransport() wrapper.makeConnection(transport) return wrapper
def test_factoryLogPrefixFallback(self): """ If the wrapped factory doesn't have a L{logPrefix} method, L{WrappingFactory.logPrefix} falls back to the factory class name. """ class NoFactory(object): pass server = NoFactory() factory = policies.WrappingFactory(server) self.assertEqual("NoFactory (WrappingFactory)", factory.logPrefix())
def test_startedConnecting(self): """ L{policies.WrappingFactory.startedConnecting} calls C{startedConnecting} on the underlying factory. """ result = [] class Factory(object): def startedConnecting(self, connector): result.append(connector) wrapper = policies.WrappingFactory(Factory()) connector = object() wrapper.startedConnecting(connector) self.assertEqual(result, [connector])
def test_protocolLogPrefixFallback(self): """ If the wrapped protocol doesn't have a L{logPrefix} method, L{ProtocolWrapper.logPrefix} falls back to the protocol class name. """ class NoProtocol: pass server = Server() server.protocol = NoProtocol factory = policies.WrappingFactory(server) protocol = factory.buildProtocol( address.IPv4Address("TCP", "127.0.0.1", 35)) self.assertEqual("NoProtocol (ProtocolWrapper)", protocol.logPrefix())
def loopbackTCP(server, client, port=0, noisy=True): """Run session between server and client protocol instances over TCP.""" from twisted.internet import reactor f = policies.WrappingFactory(protocol.Factory()) serverWrapper = _FireOnClose(f, server) f.noisy = noisy f.buildProtocol = lambda addr: serverWrapper serverPort = reactor.listenTCP(port, f, interface='127.0.0.1') clientF = LoopbackClientFactory(client) clientF.noisy = noisy reactor.connectTCP('127.0.0.1', serverPort.getHost().port, clientF) d = clientF.deferred d.addCallback(lambda x: serverWrapper.deferred) d.addCallback(lambda x: serverPort.stopListening()) return d
def test_clientConnectionFailed(self): """ L{policies.WrappingFactory.clientConnectionFailed} calls C{clientConnectionFailed} on the underlying factory. """ result = [] class Factory(object): def clientConnectionFailed(self, connector, reason): result.append((connector, reason)) wrapper = policies.WrappingFactory(Factory()) connector = object() reason = object() wrapper.clientConnectionFailed(connector, reason) self.assertEqual(result, [(connector, reason)])
def _spawn_httpbin_process(self, reactor): """ Spawn an ``httpbin`` process, returning a :py:class:`Deferred` that fires with the process transport and result. """ server = _HTTPBinServerProcessProtocol( all_data_received=self._all_data_received, terminated=self._terminated) argv = [ sys.executable, '-m', 'treq.test.local_httpbin.child', ] if self._https: argv.append('--https') with self._open(self._error_log_path, 'wb') as error_log: endpoint = endpoints.ProcessEndpoint( reactor, sys.executable, argv, env=os.environ, childFDs={ 1: 'r', 2: error_log.fileno(), }, ) # Processes are spawned synchronously. spawned = endpoint.connect( # ProtocolWrapper, WrappingFactory's protocol, has a # disconnecting attribute. See # https://twistedmatrix.com/trac/ticket/6606 policies.WrappingFactory( protocol.Factory.forProtocol(lambda: server), ), ) def wait_for_protocol(connected_protocol): process = connected_protocol.transport return self._all_data_received.addCallback( return_result_and_process, process, ) def return_result_and_process(description, process): return description, process return spawned.addCallback(wait_for_protocol)
def loopbackUNIX(server, client, noisy=True): """Run session between server and client protocol instances over UNIX socket.""" path = tempfile.mktemp() from twisted.internet import reactor f = policies.WrappingFactory(protocol.Factory()) serverWrapper = _FireOnClose(f, server) f.noisy = noisy f.buildProtocol = lambda addr: serverWrapper serverPort = reactor.listenUNIX(path, f) clientF = LoopbackClientFactory(client) clientF.noisy = noisy reactor.connectUNIX(path, clientF) d = clientF.deferred d.addCallback(lambda x: serverWrapper.deferred) d.addCallback(lambda x: serverPort.stopListening()) return d
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 listenSSL(port, factory, contextFactory, backlog=5, interface='', reactor=twisted.internet.reactor, postConnectionCheck=_alwaysSucceedsPostConnectionCheck): """ A convenience function to listen for SSL/TLS connections using Twisted. See IReactorSSL interface in Twisted. """ wrappingFactory = policies.WrappingFactory(factory) wrappingFactory.protocol = lambda factory, wrappedProtocol: \ TLSProtocolWrapper(factory, wrappedProtocol, startPassThrough=0, client=0, contextFactory=contextFactory, postConnectionCheck=postConnectionCheck) return reactor.listenTCP(port, wrappingFactory, backlog, interface)
def connectSSL(host, port, factory, contextFactory, timeout=30, bindAddress=None, reactor=twisted.internet.reactor, postConnectionCheck=Checker()): # type: (str, int, object, object, int, Optional[str], twisted.internet.reactor, Checker) -> reactor.connectTCP """ A convenience function to start an SSL/TLS connection using Twisted. See IReactorSSL interface in Twisted. """ wrappingFactory = policies.WrappingFactory(factory) wrappingFactory.protocol = lambda factory, wrappedProtocol: \ TLSProtocolWrapper(factory, wrappedProtocol, startPassThrough=0, client=1, contextFactory=contextFactory, postConnectionCheck=postConnectionCheck) return reactor.connectTCP(host, port, wrappingFactory, timeout, bindAddress)
def listenTCP(port, factory, backlog=5, interface='', reactor=twisted.internet.reactor, postConnectionCheck=None): """ A convenience function to listen for TCP connections using Twisted. NOTE: You must call startTLS(ctx) to go into SSL/TLS mode. See IReactorTCP interface in Twisted. """ wrappingFactory = policies.WrappingFactory(factory) wrappingFactory.protocol = lambda factory, wrappedProtocol: \ TLSProtocolWrapper(factory, wrappedProtocol, startPassThrough=1, client=0, contextFactory=None, postConnectionCheck=postConnectionCheck) return reactor.listenTCP(port, wrappingFactory, backlog, interface)
def __init__(self, bbApp, url, circ, successCB, failureCB=None, progressCB=None, fileName=None, timeout=None): """Signal the main thread to launch an external connection and let us handle which circuit to attach it to. @param url: location to download from @type url: str (URL) @param circ: a circuit to tunnel the request over, if necessary @type circ: Circuit or None @param successCB: function to call when the download has finished successfully @type successCB: function(data, httpDownloadInstance) @param failureCB: function to call when the download has finished successfully @type failureCB: function(reason, httpDownloadInstance) or None if you dont care about failures @param progressCB: function to call as there is periodic progress @type progressCB: function(progress) @param fileName: file to store the data to, if necessary. If None, data will be returned to the success function. If non-None, the filename will be returned instead @type fileName: str @param timeout: how long to wait for a response before assuming that it failed IMPORTANT NOTE: this is how long to wait for the SERVER. Total timeout will be timeout + time to wait for circuit, if there is a circuit Note that circuits have timeouts for being built, and setting up PAR @type timeout: float (seconds) or None""" self.url = url if circ: assert not circ.is_done( ), "Cannot download through a circuit (%s) that is finished" % ( circ.id) self.circ = circ self.fileName = fileName if not self.fileName: self.file = ClosableStringIO() else: self.file = open(self.fileName, "wb") self.successCB = successCB self.failureCB = failureCB self.progressCB = progressCB self.start_time = time.time() self.factory = None #: will eventually point to the protocol object for this test self.protocolInstance = None self.wrappingFactory = None self.requestDone = False #whether to use a TLS connection self.useTLS = False if self.url[0:5].lower() == "https": self.useTLS = True #extract the host to connect to: self.remoteHost = urlparse(self.url)[1] #extract the port to connect to: self.remotePort = 80 if self.useTLS: self.remotePort = 443 if self.remoteHost.find(":") != -1: self.remoteHost, self.remotePort = self.remoteHost.split(":") self.remotePort = int(self.remotePort) log_msg("HTTP REQUEST: %s" % (Basic.clean(self.url)), 4) self.factory = TestHTTPClientFactory(self, self.url, self.file) if self.progressCB: self.factory.protocol = MonitoredHTTPPageDownloader if self.useTLS: wrappingFactory = policies.WrappingFactory(self.factory) def wrap_protocol(factory, wrappedProtocol): checker = SSL.Checker.Checker(host=self.remoteHost) p = SSL.TwistedProtocolWrapper.TLSProtocolWrapper( factory, wrappedProtocol, startPassThrough=0, client=1, contextFactory=ClientContextFactory(), postConnectionCheck=checker) factory.protocolInstance = p return p wrappingFactory.protocol = wrap_protocol wrappingFactory.deferred = self.factory.deferred self.factory = wrappingFactory _httpDownloads.append(self) try: if self.circ: d = bbApp.launch_external_factory(self.remoteHost, self.remotePort, self.factory, self.circ.handle_stream, "REQUEST: %s" % (self.url)) else: Globals.reactor.connectTCP(self.remoteHost, self.remotePort, self.factory) except Exception, e: self.failure(e) return