Ticket #1442: endpoints.diff

File endpoints.diff, 5.1 KB (added by rwall, 8 years ago)

Dreid's branch as a diff against current trunk

  • twisted/internet/endpoints.py

     
     1# -*- test-case-name: twisted.test.test_endpoints -*- 
     2 
     3from zope.interface import Interface, implements 
     4 
     5from twisted.internet import address, interfaces 
     6from twisted.internet import reactor, defer, protocol 
     7from twisted.python import components, failure 
     8from twisted.protocols import policies 
     9 
     10class _WrappingProtocol(policies.ProtocolWrapper): 
     11    # FIXME: we probably don't need to use policies.ProtocolWrapper 
     12    # with a little work we can just set up the wrappedProtocols 
     13    # transport correctly, instead of pretending to be it. 
     14    def connectionMade(self): 
     15        policies.ProtocolWrapper.connectionMade(self) 
     16        self.factory.deferred.callback(self.wrappedProtocol) 
     17 
     18class _CallableFactory(protocol.ClientFactory): 
     19    protocol = _WrappingProtocol 
     20 
     21    def __init__(self, callable): 
     22        self.callable = callable 
     23        self.deferred = defer.Deferred() 
     24 
     25    def buildProtocol(self, addr): 
     26        try: 
     27            proto = self.callable(addr) 
     28        except: 
     29            self.deferred.errback() 
     30        else: 
     31            return self.protocol(self, proto) 
     32 
     33    def registerProtocol(self, proto): 
     34        pass 
     35 
     36    def unregisterProtocol(self, proto): 
     37        pass 
     38 
     39    def clientConnectionFailed(self, connector, reason): 
     40        self.deferred.errback(reason) 
     41 
     42 
     43class TCPEndpoint(object): 
     44    implements(interfaces.IClientEndpoint, interfaces.IServerEndpoint) 
     45 
     46    def __init__(self, host='', port=0, timeout=30, 
     47                 backlog=50, bindAddress=None): 
     48 
     49        self.host = host 
     50        self.port = port 
     51        self.timeout = timeout 
     52        self.backlog = backlog 
     53        self.bindAddress = bindAddress 
     54 
     55    def connect(self, protoCreator): 
     56        wf = _CallableFactory(protoCreator) 
     57        d = defer.execute(reactor.connectTCP, self.host, self.port, wf, 
     58                          timeout=self.timeout, 
     59                          bindAddress=self.bindAddress) 
     60 
     61        d.addCallback(lambda _: wf.deferred) 
     62 
     63        return d 
     64 
     65    def listen(self, protoCreator): 
     66         wf = _CallableFactory(protoCreator) 
     67         return defer.execute(reactor.listenTCP, self.port, wf, 
     68                              backlog=self.backlog, 
     69                              interface=self.host) 
     70 
     71 
     72class UNIXEndpoint(object): 
     73    implements(interfaces.IClientEndpoint, interfaces.IServerEndpoint) 
     74 
     75    def __init__(self, address, timeout=30, checkPID=0, 
     76                 backlog=50, mode=0666, wantPID=0): 
     77        self.address = address 
     78        self.timeout = timeout 
     79        self.checkPID= checkPID 
     80        self.backlog = backlog 
     81        self.mode = mode 
     82        self.wantPID= wantPID 
     83 
     84    def connect(self, protoCreator): 
     85        wf = _CallableFactory(protoCreator) 
     86        d = defer.execute(reactor.connectUNIX, self.address, wf, 
     87                          timeout=self.timeout, 
     88                          checkPID=self.checkPID) 
     89 
     90        d.addCallback(lambda _: wf.deferred) 
     91 
     92        return d 
     93 
     94    def listen(self, protoCreator): 
     95        wf = _CallableFactory(protoCreator) 
     96        return defer.execute(reactor.listenUNIX, self.address, wf, 
     97                                                backlog=self.backlog, 
     98                                                mode=self.mode, 
     99                                                wantPID=self.wantPID) 
     100 
     101 
     102def addressToEndpoint(addr): 
     103    if isinstance(addr, address.UNIXAddress): 
     104        endpoint = UNIXEndpoint(addr.name) 
     105    elif isinstance(addr, address.IPv4Address): 
     106        if addr.type == 'TCP': 
     107            endpoint = TCPEndpoint(addr.host, 
     108                                   addr.port) 
     109 
     110        elif addr.type == 'UDP': 
     111            raise TypeError('Could not adapt: UDP Endpoints not supported') 
     112 
     113    return endpoint 
     114 
     115components.registerAdapter(addressToEndpoint, interfaces.IAddress, 
     116                           interfaces.IClientEndpoint, interfaces.IServerEndpoint) 
  • twisted/internet/interfaces.py

     
    12941294 
    12951295    def leaveGroup(addr, interface=""): 
    12961296        """Leave multicast group, return Deferred of success.""" 
     1297 
     1298class IClientEndpoint(Interface): 
     1299    """Object that represents a remote endpoint that we wish to connect to. 
     1300    """ 
     1301    def connect(callable): 
     1302        """ 
     1303        @param callable: A callable that returns a 
     1304                         L{IProtocol} instance. 
     1305        @return: A L{Deferred} that results in an L{IProtocol} upon successful 
     1306        connection otherwise a L{ConnectError} 
     1307        """ 
     1308 
     1309class IServerEndpoint(Interface): 
     1310    """Object representing an endpoint where we will listen for connections. 
     1311    """ 
     1312 
     1313    def listen(callable): 
     1314        """ 
     1315        @param callable: A callable that returns an L{IProtocol} 
     1316        @return: A L{Deferred} that results in an L{IListeningPort} or an L{CannotListenError} 
     1317        """