Issue #7322: Trying to read from a socket's file-like object after a timeout

occurred now raises an error instead of silently losing data.
Patch by Ross Lagerwall.
This commit is contained in:
Antoine Pitrou 2011-02-25 23:07:44 +00:00
parent fc1cf41911
commit 68e5c044e8
3 changed files with 26 additions and 0 deletions

View File

@ -257,6 +257,7 @@ class SocketIO(io.RawIOBase):
self._mode = mode self._mode = mode
self._reading = "r" in mode self._reading = "r" in mode
self._writing = "w" in mode self._writing = "w" in mode
self._timeout_occurred = False
def readinto(self, b): def readinto(self, b):
"""Read up to len(b) bytes into the writable buffer *b* and return """Read up to len(b) bytes into the writable buffer *b* and return
@ -268,9 +269,14 @@ class SocketIO(io.RawIOBase):
""" """
self._checkClosed() self._checkClosed()
self._checkReadable() self._checkReadable()
if self._timeout_occurred:
raise IOError("cannot read from timed out object")
while True: while True:
try: try:
return self._sock.recv_into(b) return self._sock.recv_into(b)
except timeout:
self._timeout_occurred = True
raise
except error as e: except error as e:
n = e.args[0] n = e.args[0]
if n == EINTR: if n == EINTR:

View File

@ -1109,6 +1109,23 @@ class FileObjectClassTestCase(SocketConnectedTest):
self.write_file = None self.write_file = None
SocketConnectedTest.clientTearDown(self) SocketConnectedTest.clientTearDown(self)
def testReadAfterTimeout(self):
# Issue #7322: A file object must disallow further reads
# after a timeout has occurred.
self.cli_conn.settimeout(1)
self.read_file.read(3)
# First read raises a timeout
self.assertRaises(socket.timeout, self.read_file.read, 1)
# Second read is disallowed
with self.assertRaises(IOError) as ctx:
self.read_file.read(1)
self.assertIn("cannot read from timed out object", str(ctx.exception))
def _testReadAfterTimeout(self):
self.write_file.write(self.write_msg[0:3])
self.write_file.flush()
self.serv_finished.wait()
def testSmallRead(self): def testSmallRead(self):
# Performing small file read test # Performing small file read test
first_seg = self.read_file.read(len(self.read_msg)-3) first_seg = self.read_file.read(len(self.read_msg)-3)

View File

@ -35,6 +35,9 @@ Core and Builtins
Library Library
------- -------
- Issue #7322: Trying to read from a socket's file-like object after a timeout
occurred now raises an error instead of silently losing data.
- Issue 11291: poplib.POP no longer suppresses errors on quit(). - Issue 11291: poplib.POP no longer suppresses errors on quit().
- Issue 11177: asyncore's create_socket() arguments can now be omitted. - Issue 11177: asyncore's create_socket() arguments can now be omitted.