Moved GreenSSLObject into eventlet.green.socket, cleaned up imports slightly, removed PyOpenSSL dependency -- it will warn you if you need to install it.
This commit is contained in:
@@ -9,10 +9,8 @@ except AttributeError:
|
||||
pass
|
||||
|
||||
from eventlet.api import get_hub
|
||||
from eventlet.util import wrap_ssl_obj
|
||||
from eventlet.greenio import GreenSocket as socket
|
||||
from eventlet.greenio import GreenSSL as _GreenSSL
|
||||
from eventlet.greenio import GreenSSLObject as _GreenSSLObject
|
||||
from eventlet.greenio import SSL as _SSL
|
||||
|
||||
def fromfd(*args):
|
||||
return socket(__socket.fromfd(*args))
|
||||
@@ -78,5 +76,73 @@ def create_connection(address, timeout=_GLOBAL_DEFAULT_TIMEOUT):
|
||||
raise error, msg
|
||||
|
||||
|
||||
def ssl(sock, certificate=None, private_key=None):
|
||||
return wrap_ssl_obj(sock, certificate, private_key)
|
||||
def _convert_to_sslerror(ex):
|
||||
""" Transliterates SSL.SysCallErrors to socket.sslerrors"""
|
||||
return socket.sslerror((ex[0], ex[1]))
|
||||
|
||||
|
||||
class GreenSSLObject(object):
|
||||
""" Wrapper object around the SSLObjects returned by socket.ssl, which have a
|
||||
slightly different interface from SSL.Connection objects. """
|
||||
def __init__(self, green_ssl_obj):
|
||||
""" Should only be called by a 'green' socket.ssl """
|
||||
self.connection = green_ssl_obj
|
||||
try:
|
||||
# if it's already connected, do the handshake
|
||||
self.connection.getpeername()
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
self.connection.do_handshake()
|
||||
except _SSL.SysCallError, e:
|
||||
raise _convert_to_sslerror(e)
|
||||
|
||||
def read(self, n=None):
|
||||
"""If n is provided, read n bytes from the SSL connection, otherwise read
|
||||
until EOF. The return value is a string of the bytes read."""
|
||||
if n is None:
|
||||
# don't support this until someone needs it
|
||||
raise NotImplementedError("GreenSSLObject does not support "\
|
||||
" unlimited reads until we hear of someone needing to use them.")
|
||||
else:
|
||||
try:
|
||||
return self.connection.read(n)
|
||||
except _SSL.ZeroReturnError:
|
||||
return ''
|
||||
except _SSL.SysCallError, e:
|
||||
raise _convert_to_sslerror(e)
|
||||
|
||||
def write(self, s):
|
||||
"""Writes the string s to the on the object's SSL connection.
|
||||
The return value is the number of bytes written. """
|
||||
try:
|
||||
return self.connection.write(s)
|
||||
except _SSL.SysCallError, e:
|
||||
raise _convert_to_sslerror(e)
|
||||
|
||||
def server(self):
|
||||
""" Returns a string describing the server's certificate. Useful for debugging
|
||||
purposes; do not parse the content of this string because its format can't be
|
||||
parsed unambiguously. """
|
||||
return str(self.connection.get_peer_certificate().get_subject())
|
||||
|
||||
def issuer(self):
|
||||
"""Returns a string describing the issuer of the server's certificate. Useful
|
||||
for debugging purposes; do not parse the content of this string because its
|
||||
format can't be parsed unambiguously."""
|
||||
return str(self.connection.get_peer_certificate().get_issuer())
|
||||
|
||||
|
||||
try:
|
||||
from eventlet.green import ssl
|
||||
def ssl(sock, certificate=None, private_key=None):
|
||||
warnings.warn("socket.ssl() is deprecated. Use ssl.wrap_socket() instead.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return ssl.sslwrap_simple(sock, keyfile, certfile)
|
||||
except ImportError:
|
||||
def ssl(sock, certificate=None, private_key=None):
|
||||
from eventlet import util
|
||||
wrapped = util.wrap_ssl(sock, certificate, private_key)
|
||||
return GreenSSLObject(wrapped)
|
||||
|
||||
|
@@ -8,7 +8,7 @@ import time
|
||||
|
||||
from eventlet.api import trampoline, getcurrent
|
||||
from thread import get_ident
|
||||
from eventlet.greenio import set_nonblocking, GreenSocket, GreenSSLObject, SOCKET_CLOSED, CONNECT_ERR, CONNECT_SUCCESS
|
||||
from eventlet.greenio import set_nonblocking, GreenSocket, SOCKET_CLOSED, CONNECT_ERR, CONNECT_SUCCESS
|
||||
orig_socket = __import__('socket')
|
||||
socket = orig_socket.socket
|
||||
|
||||
@@ -290,6 +290,7 @@ def sslwrap_simple(sock, keyfile=None, certfile=None):
|
||||
"""A replacement for the old socket.ssl function. Designed
|
||||
for compability with Python 2.5 and earlier. Will disappear in
|
||||
Python 3.0."""
|
||||
from eventlet.green.socket import GreenSSLObject
|
||||
ssl_sock = GreenSSLSocket(sock, 0, keyfile, certfile, CERT_NONE,
|
||||
PROTOCOL_SSLv23, None)
|
||||
return GreenSSLObject(ssl_sock)
|
||||
|
@@ -1,6 +1,4 @@
|
||||
from eventlet.api import trampoline, get_hub
|
||||
from eventlet import util
|
||||
|
||||
|
||||
BUFFER_SIZE = 4096
|
||||
|
||||
@@ -712,67 +710,3 @@ def shutdown_safe(sock):
|
||||
if e[0] != errno.ENOTCONN:
|
||||
raise
|
||||
|
||||
|
||||
def _convert_to_sslerror(ex):
|
||||
""" Transliterates SSL.SysCallErrors to socket.sslerrors"""
|
||||
return socket.sslerror((ex[0], ex[1]))
|
||||
|
||||
|
||||
class GreenSSLObject(object):
|
||||
""" Wrapper object around the SSLObjects returned by socket.ssl, which have a
|
||||
slightly different interface from SSL.Connection objects. """
|
||||
def __init__(self, green_ssl_obj):
|
||||
""" Should only be called by a 'green' socket.ssl """
|
||||
try:
|
||||
from eventlet.green.ssl import GreenSSLSocket
|
||||
except ImportError:
|
||||
class GreenSSLSocket(object):
|
||||
pass
|
||||
|
||||
assert isinstance(green_ssl_obj, (GreenSSL, GreenSSLSocket))
|
||||
self.connection = green_ssl_obj
|
||||
try:
|
||||
# if it's already connected, do the handshake
|
||||
self.connection.getpeername()
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
self.connection.do_handshake()
|
||||
except SSL.SysCallError, e:
|
||||
raise _convert_to_sslerror(e)
|
||||
|
||||
def read(self, n=None):
|
||||
"""If n is provided, read n bytes from the SSL connection, otherwise read
|
||||
until EOF. The return value is a string of the bytes read."""
|
||||
if n is None:
|
||||
# don't support this until someone needs it
|
||||
raise NotImplementedError("GreenSSLObject does not support "\
|
||||
" unlimited reads until we hear of someone needing to use them.")
|
||||
else:
|
||||
try:
|
||||
return self.connection.read(n)
|
||||
except SSL.ZeroReturnError:
|
||||
return ''
|
||||
except SSL.SysCallError, e:
|
||||
raise _convert_to_sslerror(e)
|
||||
|
||||
def write(self, s):
|
||||
"""Writes the string s to the on the object's SSL connection.
|
||||
The return value is the number of bytes written. """
|
||||
try:
|
||||
return self.connection.write(s)
|
||||
except SSL.SysCallError, e:
|
||||
raise _convert_to_sslerror(e)
|
||||
|
||||
def server(self):
|
||||
""" Returns a string describing the server's certificate. Useful for debugging
|
||||
purposes; do not parse the content of this string because its format can't be
|
||||
parsed unambiguously. """
|
||||
return str(self.connection.get_peer_certificate().get_subject())
|
||||
|
||||
def issuer(self):
|
||||
"""Returns a string describing the issuer of the server's certificate. Useful
|
||||
for debugging purposes; do not parse the content of this string because its
|
||||
format can't be parsed unambiguously."""
|
||||
return str(self.connection.get_peer_certificate().get_issuer())
|
||||
|
@@ -3,6 +3,8 @@ import select
|
||||
import socket
|
||||
import errno
|
||||
|
||||
from eventlet import greenio
|
||||
|
||||
def g_log(*args):
|
||||
import sys
|
||||
from eventlet.support import greenlets as greenlet
|
||||
@@ -37,27 +39,21 @@ def tcp_socket():
|
||||
|
||||
try:
|
||||
# if ssl is available, use eventlet.green.ssl for our ssl implementation
|
||||
import ssl as _ssl
|
||||
from eventlet.green import ssl
|
||||
def wrap_ssl(sock, certificate=None, private_key=None, server_side=False):
|
||||
from eventlet.green import ssl
|
||||
return ssl.wrap_socket(sock,
|
||||
keyfile=private_key, certfile=certificate,
|
||||
server_side=server_side, cert_reqs=ssl.CERT_NONE,
|
||||
ssl_version=ssl.PROTOCOL_SSLv23, ca_certs=None,
|
||||
do_handshake_on_connect=True,
|
||||
suppress_ragged_eofs=True)
|
||||
|
||||
def wrap_ssl_obj(sock, certificate=None, private_key=None):
|
||||
from eventlet import ssl
|
||||
warnings.warn("socket.ssl() is deprecated. Use ssl.wrap_socket() instead.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
return ssl.sslwrap_simple(sock, keyfile, certfile)
|
||||
|
||||
suppress_ragged_eofs=True)
|
||||
except ImportError:
|
||||
# if ssl is not available, use PyOpenSSL
|
||||
def wrap_ssl(sock, certificate=None, private_key=None, server_side=False):
|
||||
from OpenSSL import SSL
|
||||
from eventlet import greenio
|
||||
try:
|
||||
from OpenSSL import SSL
|
||||
except ImportError:
|
||||
raise ImportError("To use SSL with Eventlet, you must install PyOpenSSL or use Python 2.6 or later.")
|
||||
context = SSL.Context(SSL.SSLv23_METHOD)
|
||||
if certificate is not None:
|
||||
context.use_certificate_file(certificate)
|
||||
@@ -71,13 +67,6 @@ except ImportError:
|
||||
else:
|
||||
connection.set_connect_state()
|
||||
return greenio.GreenSSL(connection)
|
||||
|
||||
def wrap_ssl_obj(sock, certificate=None, private_key=None):
|
||||
""" For 100% compatibility with the socket module, this wraps and handshakes an
|
||||
open connection, returning a SSLObject."""
|
||||
from eventlet import greenio
|
||||
wrapped = wrap_ssl(sock, certificate, private_key)
|
||||
return greenio.GreenSSLObject(wrapped)
|
||||
|
||||
socket_already_wrapped = False
|
||||
def wrap_socket_with_coroutine_socket(use_thread_pool=True):
|
||||
@@ -85,12 +74,9 @@ def wrap_socket_with_coroutine_socket(use_thread_pool=True):
|
||||
if socket_already_wrapped:
|
||||
return
|
||||
|
||||
def new_socket(*args, **kw):
|
||||
from eventlet import greenio
|
||||
return greenio.GreenSocket(__original_socket__(*args, **kw))
|
||||
socket.socket = new_socket
|
||||
|
||||
socket.ssl = wrap_ssl_obj
|
||||
import eventlet.green.socket
|
||||
socket.socket = eventlet.green.socket.socket
|
||||
socket.ssl = eventlet.green.socket.ssl
|
||||
try:
|
||||
import ssl as _ssl
|
||||
from eventlet.green import ssl
|
||||
@@ -115,7 +101,6 @@ def wrap_socket_with_coroutine_socket(use_thread_pool=True):
|
||||
|
||||
if __original_fromfd__ is not None:
|
||||
def new_fromfd(*args, **kw):
|
||||
from eventlet import greenio
|
||||
return greenio.GreenSocket(__original_fromfd__(*args, **kw))
|
||||
socket.fromfd = new_fromfd
|
||||
|
||||
@@ -136,7 +121,6 @@ def wrap_pipes_with_coroutine_pipes():
|
||||
if pipes_already_wrapped:
|
||||
return
|
||||
def new_fdopen(*args, **kw):
|
||||
from eventlet import greenio
|
||||
return greenio.GreenPipe(__original_fdopen__(*args, **kw))
|
||||
def new_read(fd, *args, **kw):
|
||||
from eventlet import api
|
||||
|
3
setup.py
3
setup.py
@@ -6,8 +6,7 @@ from eventlet import __version__
|
||||
import sys
|
||||
|
||||
requirements = []
|
||||
for flag, req in [('--without-greenlet','greenlet >= 0.2'),
|
||||
('--without-pyopenssl', 'pyopenssl')]:
|
||||
for flag, req in [('--without-greenlet','greenlet >= 0.2')]:
|
||||
if flag in sys.argv:
|
||||
sys.argv.remove(flag)
|
||||
else:
|
||||
|
@@ -1,6 +1,7 @@
|
||||
from tests import skipped, LimitedTestCase, skip_with_libevent, TestIsTakingTooLong
|
||||
from unittest import main
|
||||
from eventlet import api, util, coros, proc, greenio
|
||||
from eventlet.green.socket import GreenSSLObject
|
||||
import os
|
||||
import socket
|
||||
import sys
|
||||
@@ -282,7 +283,7 @@ class SSLTest(LimitedTestCase):
|
||||
self.private_key_file)
|
||||
killer = api.spawn(serve, listener)
|
||||
client = util.wrap_ssl(api.connect_tcp(('localhost', listener.getsockname()[1])))
|
||||
client = greenio.GreenSSLObject(client)
|
||||
client = GreenSSLObject(client)
|
||||
self.assertEquals(client.read(1024), 'content')
|
||||
self.assertEquals(client.read(1024), '')
|
||||
|
||||
@@ -290,7 +291,10 @@ class SSLTest(LimitedTestCase):
|
||||
def serve(listener):
|
||||
sock, addr = listener.accept()
|
||||
stuff = sock.read(8192)
|
||||
empt = sock.read(8192)
|
||||
try:
|
||||
self.assertEquals("", sock.read(8192))
|
||||
except greenio.SSL.ZeroReturnError:
|
||||
pass
|
||||
|
||||
sock = api.ssl_listener(('127.0.0.1', 0), self.certificate_file, self.private_key_file)
|
||||
server_coro = coros.execute(serve, sock)
|
||||
|
Reference in New Issue
Block a user