[Twisted-Python] half-closing SSL connection, unexpected connectionLost() error
Denis Bilenko
denis.bilenko at gmail.com
Fri Feb 13 09:35:33 EST 2009
Hi,
What's the correct way to call loseWriteConnection on SSL connection?
I keep getting "Connection was closed in a non-clean fashion" errors
when I do that.
Here's a minimal server and a client that trigger the error. Note that
the server
does not implement IHalfCloseableProtocol and I'd like to keep it that way
(primarily because I'm building a client, not a server, so I'd like my client to
work with as many servers as possible)
---------------------------------------------------------------------------
server.py
from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor
class MyProtocol(Protocol):
def connectionMade(self):
print self.transport.getHost(), self.transport.getPeer()
def connectionLost(self, reason):
print 'connectionLost %r' % reason.value
class MyFactory(Factory):
protocol = MyProtocol
from twisted.internet import ssl
contextFactory = ssl.DefaultOpenSSLContextFactory('valid.key',
'valid.crt', sslmethod=ssl.SSL.SSLv3_METHOD)
reactor.listenSSL(10000, MyFactory(), contextFactory)
reactor.run()
---------------------------------------------------------------------------
client.py
import sys
from zope.interface import implements
from twisted.internet.protocol import ClientFactory, Protocol
from twisted.internet.interfaces import IHalfCloseableProtocol
from twisted.internet import reactor
class MyProtocol(Protocol):
implements(IHalfCloseableProtocol)
def connectionMade(self):
print 'connectionMade %s -> %s' % (self.transport.getHost(),
self.transport.getPeer())
self.transport.loseWriteConnection()
def readConnectionLost(self):
print 'readConnectionLost'
def writeConnectionLost(self):
print 'writeConnectionLost'
def connectionLost(self, reason):
print 'connectionLost %r' % reason.value
class MyFactory(ClientFactory):
protocol = MyProtocol
def clientConnectionFailed(self, connector, err):
print err.value
reactor.stop()
from twisted.internet import ssl
contextFactory = ssl.ClientContextFactory()
reactor.connectSSL(sys.argv[1], int(sys.argv[2]), MyFactory(), contextFactory)
reactor.run()
---------------------------------------------------------------------------
console1
$ python server.py
IPv4Address(TCP, '127.0.0.1', 10000) IPv4Address(TCP, '127.0.0.1', 40291)
connectionLost ConnectionDone()
---------------------------------------------------------------------------
console2
$ python client.py localhost 10000
connectionMade IPv4Address(TCP, '127.0.0.1', 40291) ->
IPv4Address(TCP, 'localhost', 10000)
writeConnectionLost
connectionLost ConnectionLost()
The question is why it's not ConnectionDone but ConnectionLost that
client receives
in connectionLost callback?
If I convert the examples to use TCP, I get ConnectionDone, as expected.
Thank you for your time.
More information about the Twisted-Python
mailing list