@@ -83,14 +83,20 @@ def _is_ip_address(address):
8383 _SSL .WantReadError , _SSL .WantWriteError , _SSL .WantX509LookupError )
8484
8585
86+ def _ragged_eof (exc ):
87+ """Return True if the OpenSSL.SSL.SysCallError is a ragged EOF."""
88+ return exc .args == (- 1 , 'Unexpected EOF' )
89+
90+
8691# https://github.com/pyca/pyopenssl/issues/168
8792# https://github.com/pyca/pyopenssl/issues/176
8893# https://docs.python.org/3/library/ssl.html#notes-on-non-blocking-sockets
8994class _sslConn (_SSL .Connection ):
9095
91- def __init__ (self , * args , ** kwargs ):
96+ def __init__ (self , ctx , sock , suppress_ragged_eofs ):
9297 self .socket_checker = _SocketChecker ()
93- super (_sslConn , self ).__init__ (* args , ** kwargs )
98+ self .suppress_ragged_eofs = suppress_ragged_eofs
99+ super (_sslConn , self ).__init__ (ctx , sock )
94100
95101 def _call (self , call , * args , ** kwargs ):
96102 timeout = self .gettimeout ()
@@ -110,10 +116,22 @@ def do_handshake(self, *args, **kwargs):
110116 return self ._call (super (_sslConn , self ).do_handshake , * args , ** kwargs )
111117
112118 def recv (self , * args , ** kwargs ):
113- return self ._call (super (_sslConn , self ).recv , * args , ** kwargs )
119+ try :
120+ return self ._call (super (_sslConn , self ).recv , * args , ** kwargs )
121+ except _SSL .SysCallError as exc :
122+ # Suppress ragged EOFs to match the stdlib.
123+ if self .suppress_ragged_eofs and _ragged_eof (exc ):
124+ return b""
125+ raise
114126
115127 def recv_into (self , * args , ** kwargs ):
116- return self ._call (super (_sslConn , self ).recv_into , * args , ** kwargs )
128+ try :
129+ return self ._call (super (_sslConn , self ).recv_into , * args , ** kwargs )
130+ except _SSL .SysCallError as exc :
131+ # Suppress ragged EOFs to match the stdlib.
132+ if self .suppress_ragged_eofs and _ragged_eof (exc ):
133+ return 0
134+ raise
117135
118136 def sendall (self , buf , flags = 0 ):
119137 view = memoryview (buf )
@@ -266,12 +284,12 @@ def set_default_verify_paths(self):
266284
267285 def wrap_socket (self , sock , server_side = False ,
268286 do_handshake_on_connect = True ,
269- suppress_ragged_eofs = True , # TODO: Add support to _sslConn.
287+ suppress_ragged_eofs = True ,
270288 server_hostname = None , session = None ):
271289 """Wrap an existing Python socket sock and return a TLS socket
272290 object.
273291 """
274- ssl_conn = _sslConn (self ._ctx , sock )
292+ ssl_conn = _sslConn (self ._ctx , sock , suppress_ragged_eofs )
275293 if session :
276294 ssl_conn .set_session (session )
277295 if server_side is True :
0 commit comments