Both read and write behave properly with regard to WantRead and WantWrite; send and sendall aliased to write.
This commit is contained in:
@@ -559,9 +559,8 @@ class GreenSSL(GreenSocket):
|
|||||||
self._refcount = RefCount()
|
self._refcount = RefCount()
|
||||||
|
|
||||||
def read(self, size=None):
|
def read(self, size=None):
|
||||||
""" Read up to *size* bytes from the socket. This may return fewer than
|
"""Works like a blocking call to SSL_read(), whose behavior is
|
||||||
*size* bytes in some circumstances, but everything appears to work as
|
described here: http://www.openssl.org/docs/ssl/SSL_read.html"""
|
||||||
long as you don't treat this precisely like standard socket read()."""
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
return self.fd.read(size)
|
return self.fd.read(size)
|
||||||
@@ -570,21 +569,38 @@ class GreenSSL(GreenSocket):
|
|||||||
read=True,
|
read=True,
|
||||||
timeout=self.timeout,
|
timeout=self.timeout,
|
||||||
timeout_exc=socket.timeout)
|
timeout_exc=socket.timeout)
|
||||||
|
except util.SSL.WantWriteError:
|
||||||
|
trampoline(self.fd.fileno(),
|
||||||
|
write=True,
|
||||||
|
timeout=self.timeout,
|
||||||
|
timeout_exc=socket.timeout)
|
||||||
|
except util.SSL.SysCallError, e:
|
||||||
|
if e[0] == -1:
|
||||||
|
return ''
|
||||||
|
|
||||||
recv = read
|
recv = read
|
||||||
|
|
||||||
def sendall(self, data):
|
|
||||||
# overriding sendall because ssl sockets behave badly when asked to
|
|
||||||
# send empty strings; 'normal' sockets don't have a problem
|
|
||||||
if not data:
|
|
||||||
return
|
|
||||||
super(GreenSSL, self).sendall(data)
|
|
||||||
|
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
try:
|
"""Works like a blocking call to SSL_write(), whose behavior is
|
||||||
return self.sendall(data)
|
described here: http://www.openssl.org/docs/ssl/SSL_write.html"""
|
||||||
except util.SSL.Error, ex:
|
if not data:
|
||||||
raise socket.sslerror(str(ex))
|
return 0 # calling SSL_write() with 0 bytes to be sent is undefined
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
return self.fd.write(data)
|
||||||
|
except util.SSL.WantReadError:
|
||||||
|
trampoline(self.fd.fileno(),
|
||||||
|
read=True,
|
||||||
|
timeout=self.timeout,
|
||||||
|
timeout_exc=socket.timeout)
|
||||||
|
except util.SSL.WantWriteError:
|
||||||
|
trampoline(self.fd.fileno(),
|
||||||
|
write=True,
|
||||||
|
timeout=self.timeout,
|
||||||
|
timeout_exc=socket.timeout)
|
||||||
|
|
||||||
|
sendall = write
|
||||||
|
send = write
|
||||||
|
|
||||||
def server(self):
|
def server(self):
|
||||||
return self.fd.server()
|
return self.fd.server()
|
||||||
@@ -595,12 +611,16 @@ class GreenSSL(GreenSocket):
|
|||||||
def dup(self):
|
def dup(self):
|
||||||
raise NotImplementedError("Dup not supported on SSL sockets")
|
raise NotImplementedError("Dup not supported on SSL sockets")
|
||||||
|
|
||||||
|
# TODO: remove and fix wsgi.py so that it doesn't call makefile on
|
||||||
|
# ssl sockets (see http://code.activestate.com/recipes/442473/)
|
||||||
def makefile(self, *args, **kw):
|
def makefile(self, *args, **kw):
|
||||||
self._refcount.increment()
|
self._refcount.increment()
|
||||||
return GreenFile(type(self)(self.fd, refcount = self._refcount))
|
return GreenFile(type(self)(self.fd, refcount = self._refcount))
|
||||||
|
|
||||||
|
# TODO: remove along with makefile
|
||||||
makeGreenFile = makefile
|
makeGreenFile = makefile
|
||||||
|
|
||||||
|
# TODO: remove along with makefile
|
||||||
def close(self):
|
def close(self):
|
||||||
self._refcount.decrement()
|
self._refcount.decrement()
|
||||||
if self._refcount.is_referenced():
|
if self._refcount.is_referenced():
|
||||||
|
Reference in New Issue
Block a user