From 53fe3753d8b0e25f0e550116cf3fcbbdc095b379 Mon Sep 17 00:00:00 2001 From: Illia Volochii Date: Tue, 27 Feb 2024 20:48:50 +0200 Subject: [PATCH] gh-115997: Make `HTTPResponse.read1` and `readline` raise `IncompleteRead` --- Lib/http/client.py | 4 ++++ Lib/test/test_httplib.py | 24 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/Lib/http/client.py b/Lib/http/client.py index a353716a8506e65..4a5f97e5ff8bcc1 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -663,6 +663,8 @@ def read1(self, n=-1): result = self.fp.read1(n) if not result and n: self._close_conn() + if self.length: + raise IncompleteRead(result, self.length) elif self.length is not None: self.length -= len(result) if not self.length: @@ -689,6 +691,8 @@ def readline(self, limit=-1): result = self.fp.readline(limit) if not result and limit: self._close_conn() + if self.length: + raise IncompleteRead(result, self.length) elif self.length is not None: self.length -= len(result) if not self.length: diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index 6e63a8872d9c6e1..eb776833df4d2a9 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -1608,6 +1608,30 @@ class ExtendedReadTestContentLengthKnown(ExtendedReadTest): _header, _body = ExtendedReadTest.lines.split('\r\n\r\n', 1) lines = _header + f'\r\nContent-Length: {len(_body)}\r\n\r\n' + _body + def _test_incomplete_read(self, read_meth): + resp = self.resp + # Reduce the size of content the response object will read to + # cause the incomplete read. + resp.fp.read(1) + with self.assertRaises(client.IncompleteRead) as cm: + while True: + data = resp.read1() + if not data: + break + exception = cm.exception + self.assertEqual(exception.partial, b"") + self.assertEqual(exception.expected, 1) + self.assertTrue(resp.isclosed()) + + def test_read_incomplete_read(self): + self._test_incomplete_read(self.resp.read) + + def test_read1_incomplete_read(self): + self._test_incomplete_read(self.resp.read1) + + def test_readline_incomplete_read(self): + self._test_incomplete_read(self.resp.readline) + class ExtendedReadTestChunked(ExtendedReadTest): """