-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathSSL.py
More file actions
89 lines (72 loc) · 2.91 KB
/
SSL.py
File metadata and controls
89 lines (72 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
"""gevent_openssl.SSL - gevent compatibility with OpenSSL.SSL (pyOpenSSL)
"""
import OpenSSL.SSL
from gevent.socket import wait_read, wait_write
_real_connection = OpenSSL.SSL.Connection
class Connection(object):
"""OpenSSL Connection wrapper
"""
_reverse_mapping = _real_connection._reverse_mapping
def __init__(self, context, sock):
self._context = context
self._sock = sock
self._connection = _real_connection(context, sock)
def __getattr__(self, attr):
return getattr(self._connection, attr)
def __iowait(self, io_func, *args, **kwargs):
fd = self._sock.fileno()
timeout = self._sock.gettimeout()
while True:
try:
return io_func(*args, **kwargs)
except (OpenSSL.SSL.WantReadError, OpenSSL.SSL.WantX509LookupError):
wait_read(fd, timeout=timeout)
except OpenSSL.SSL.WantWriteError:
wait_write(fd, timeout=timeout)
def accept(self):
sock, addr = self._sock.accept()
return Connection(self._context, sock), addr
def do_handshake(self):
return self.__iowait(self._connection.do_handshake)
def connect(self, *args, **kwargs):
return self.__iowait(self._connection.connect, *args, **kwargs)
def send(self, data, flags=0):
return self.__send(self._connection.send, data, flags)
def sendall(self, data, flags=0):
return self.__send(self._connection.sendall, data, flags)
def __send(self, send_method, data, flags=0):
try:
return self.__iowait(send_method, data, flags)
except OpenSSL.SSL.SysCallError as e:
if e[0] == -1 and not data:
# errors when writing empty strings are expected and can be
# ignored
return 0
raise
def recv(self, bufsiz, flags=0):
pending = self._connection.pending()
if pending:
return self._connection.recv(min(pending, bufsiz))
try:
return self.__iowait(self._connection.recv, bufsiz, flags)
except OpenSSL.SSL.ZeroReturnError:
return ''
except OpenSSL.SSL.SysCallError as e:
if e[0] == -1 and 'Unexpected EOF' in e[1]:
# errors when reading empty strings are expected and can be
# ignored
return ''
raise
def recv_into(self, buffer, nbytes=None, flags=None):
try:
return self.__iowait(self._connection.recv_into, buffer, nbytes, flags)
except OpenSSL.SSL.ZeroReturnError:
return ''
except OpenSSL.SSL.SysCallError as e:
if e[0] == -1 and 'Unexpected EOF' in e[1]:
# errors when reading empty strings are expected and can be
# ignored
return ''
raise
def shutdown(self):
return self.__iowait(self._connection.shutdown)