self.server_hostname = server_hostname
self.do_handshake_on_connect = do_handshake_on_connect
self.suppress_ragged_eofs = suppress_ragged_eofs
- connected = False
if sock is not None:
socket.__init__(self,
family=sock.family,
proto=sock.proto,
fileno=sock.fileno())
self.settimeout(sock.gettimeout())
- # see if it's connected
- try:
- sock.getpeername()
- except OSError as e:
- if e.errno != errno.ENOTCONN:
- raise
- else:
- connected = True
sock.detach()
elif fileno is not None:
socket.__init__(self, fileno=fileno)
else:
socket.__init__(self, family=family, type=type, proto=proto)
+ # See if we are connected
+ try:
+ self.getpeername()
+ except OSError as e:
+ if e.errno != errno.ENOTCONN:
+ raise
+ connected = False
+ else:
+ connected = True
+
self._closed = False
self._sslobj = None
self._connected = connected
except OSError as x:
self.close()
raise x
+
@property
def context(self):
return self._context
# raise an exception here if you wish to check for spurious closes
pass
+ def _check_connected(self):
+ if not self._connected:
+ # getpeername() will raise ENOTCONN if the socket is really
+ # not connected; note that we can be connected even without
+ # _connected being set, e.g. if connect() first returned
+ # EAGAIN.
+ self.getpeername()
+
def read(self, len=0, buffer=None):
"""Read up to LEN bytes and return them.
Return zero-length string on EOF."""
certificate was provided, but not validated."""
self._checkClosed()
+ self._check_connected()
return self._sslobj.peer_certificate(binary_form)
def selected_npn_protocol(self):
def _real_close(self):
self._sslobj = None
- # self._closed = True
socket._real_close(self)
def do_handshake(self, block=False):
"""Perform a TLS/SSL handshake."""
-
+ self._check_connected()
timeout = self.gettimeout()
try:
if timeout == 0.0 and block:
rc = None
socket.connect(self, addr)
if not rc:
+ self._connected = True
if self.do_handshake_on_connect:
self.do_handshake()
- self._connected = True
return rc
except OSError:
self._sslobj = None
import weakref
import platform
import functools
+from unittest import mock
ssl = support.import_module("ssl")
self.assertIsInstance(remote, ssl.SSLSocket)
self.assertEqual(peer, client_addr)
+ def test_getpeercert_enotconn(self):
+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ with context.wrap_socket(socket.socket()) as sock:
+ with self.assertRaises(OSError) as cm:
+ sock.getpeercert()
+ self.assertEqual(cm.exception.errno, errno.ENOTCONN)
+
+ def test_do_handshake_enotconn(self):
+ context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
+ with context.wrap_socket(socket.socket()) as sock:
+ with self.assertRaises(OSError) as cm:
+ sock.do_handshake()
+ self.assertEqual(cm.exception.errno, errno.ENOTCONN)
+
def test_default_ciphers(self):
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
try:
Library
-------
+- Issue #13721: SSLSocket.getpeercert() and SSLSocket.do_handshake() now
+ raise an OSError with ENOTCONN, instead of an AttributeError, when the
+ SSLSocket is not connected.
+
- Issue #14679: add an __all__ (that contains only HTMLParser) to html.parser.
- Issue #17802: Fix an UnboundLocalError in html.parser. Initial tests by