| | 1 | # -*- test-case-name: twisted.test.test_endpoints -*- |
| | 2 | |
| | 3 | from zope.interface import Interface, implements |
| | 4 | |
| | 5 | from twisted.internet import address, interfaces |
| | 6 | from twisted.internet import reactor, defer, protocol |
| | 7 | from twisted.python import components, failure |
| | 8 | from twisted.protocols import policies |
| | 9 | |
| | 10 | class _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 | |
| | 18 | class _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 | |
| | 43 | class 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 | |
| | 72 | class 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 | |
| | 102 | def 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 | |
| | 115 | components.registerAdapter(addressToEndpoint, interfaces.IAddress, |
| | 116 | interfaces.IClientEndpoint, interfaces.IServerEndpoint) |