Fix socket_recv to return '' instead of raising socket.error(errno.ECONNRESET) explicitly when using an ssl socket. This allows an eventlet ssl client to talk to an eventlet ssl server properly! Thanks, Ryan Williams.
This commit is contained in:
8
NEWS
8
NEWS
@@ -1,3 +1,9 @@
|
||||
0.7.x
|
||||
=====
|
||||
Fix a major memory leak when using the libevent or libev hubs. Timers were not being removed from the hub after they fired. (Thanks Agusto Becciu and the grugq). Also, make it possible to call wrap_socket_with_coroutine_socket without using the threadpool to make dns operations non-blocking (Thanks the grugq).
|
||||
|
||||
It's now possible to use eventlet's SSL client to talk to eventlet's SSL server. (Thanks to Ryan Williams)
|
||||
|
||||
0.6.x
|
||||
=====
|
||||
|
||||
@@ -5,8 +11,6 @@ Fixes some long-standing bugs where sometimes failures in accept() or connect()
|
||||
|
||||
0.6.1: Added eventlet.tpool.killall. Blocks until all of the threadpool threads have been told to exit and join()ed. Meant to be used to clean up the threadpool on exit or if calling execv. Used by Spawning.
|
||||
|
||||
0.6.2: Fix a major memory leak when using the libevent or libev hubs. Timers were not being removed from the hub after they fired. (Thanks Agusto Becciu). Also, make it possible to call wrap_socket_with_coroutine_socket without using the threadpool to make dns operations non-blocking (Thanks the grugq).
|
||||
|
||||
0.5.x
|
||||
=====
|
||||
|
||||
|
||||
3
README
3
README
@@ -21,9 +21,6 @@ Eventlet runs on Python version 2.3 or greater, with the following dependenceis:
|
||||
* Not enough test coverage -- the goal is 100%, but we are not there yet.
|
||||
* Eventlet does not currently run on stackless using tasklets, though
|
||||
it is a goal to do so in the future.
|
||||
* The SSL client does not properly connect to the SSL server, though
|
||||
both client and server interoperate with other SSL implementations
|
||||
(e.g. curl and apache).
|
||||
|
||||
== getting started ==
|
||||
|
||||
|
||||
@@ -22,10 +22,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
from eventlet import tests
|
||||
from eventlet import api, greenio, util
|
||||
import os
|
||||
import socket
|
||||
|
||||
from eventlet import api
|
||||
from eventlet import greenio
|
||||
from eventlet import tests
|
||||
from eventlet import util
|
||||
|
||||
|
||||
def check_hub():
|
||||
# Clear through the descriptor queue
|
||||
@@ -43,6 +47,10 @@ def check_hub():
|
||||
|
||||
class TestApi(tests.TestCase):
|
||||
mode = 'static'
|
||||
|
||||
certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')
|
||||
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
|
||||
|
||||
def test_tcp_listener(self):
|
||||
socket = api.tcp_listener(('0.0.0.0', 0))
|
||||
assert socket.getsockname()[0] == '0.0.0.0'
|
||||
@@ -74,6 +82,30 @@ class TestApi(tests.TestCase):
|
||||
|
||||
check_hub()
|
||||
|
||||
def test_connect_ssl(self):
|
||||
def accept_once(listenfd):
|
||||
try:
|
||||
conn, addr = listenfd.accept()
|
||||
fl = conn.makefile('w')
|
||||
fl.write('hello\r\n')
|
||||
fl.close()
|
||||
conn.close()
|
||||
finally:
|
||||
listenfd.close()
|
||||
|
||||
server = api.ssl_listener(('0.0.0.0', 0),
|
||||
self.certificate_file,
|
||||
self.private_key_file)
|
||||
api.spawn(accept_once, server)
|
||||
|
||||
client = util.wrap_ssl(
|
||||
api.connect_tcp(('127.0.0.1', server.getsockname()[1])))
|
||||
client = client.makefile()
|
||||
|
||||
assert client.readline() == 'hello\r\n'
|
||||
assert client.read() == ''
|
||||
client.close()
|
||||
|
||||
def test_server(self):
|
||||
connected = []
|
||||
server = api.tcp_listener(('0.0.0.0', 0))
|
||||
|
||||
@@ -137,7 +137,7 @@ def socket_recv(descriptor, buflen):
|
||||
return ''
|
||||
except util.SSL.SysCallError, e:
|
||||
if e[0] == -1 or e[0] > 0:
|
||||
raise socket.error(errno.ECONNRESET, errno.errorcode[errno.ECONNRESET])
|
||||
return ''
|
||||
raise
|
||||
finally:
|
||||
if cancel:
|
||||
@@ -213,6 +213,12 @@ class GreenSocket(object):
|
||||
if self.closed:
|
||||
return
|
||||
self.closed = True
|
||||
if self.is_secure:
|
||||
# *NOTE: This is not quite the correct SSL shutdown sequence.
|
||||
# We should actually be checking the return value of shutdown.
|
||||
# Note also that this is not the same as calling self.shutdown().
|
||||
self.fd.shutdown()
|
||||
|
||||
fn = self.close = self.fd.close
|
||||
try:
|
||||
res = fn(*args, **kw)
|
||||
@@ -296,6 +302,9 @@ class GreenSocket(object):
|
||||
return fn(*args, **kw)
|
||||
|
||||
def shutdown(self, *args, **kw):
|
||||
if self.is_secure:
|
||||
fn = self.shutdown = self.fd.sock_shutdown
|
||||
else:
|
||||
fn = self.shutdown = self.fd.shutdown
|
||||
return fn(*args, **kw)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user