From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Mon, 18 Dec 2023 20:34:15 +0000 (+0100) Subject: [3.11] gh-113199: Make read1() and readline() of HTTPResponse close IO after reading... X-Git-Tag: v3.11.8~249 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=44bdb6d55cdb036e8966efee45e4b452368d8602;p=thirdparty%2FPython%2Fcpython.git [3.11] gh-113199: Make read1() and readline() of HTTPResponse close IO after reading all data (GH-113200) (GH-113260) (cherry picked from commit 41336a72b90634d5ac74a57b6826e4dd6fe78eac) Co-authored-by: Illia Volochii --- diff --git a/Lib/http/client.py b/Lib/http/client.py index 87bca4d76aba..1ee22989ae11 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -663,6 +663,8 @@ class HTTPResponse(io.BufferedIOBase): self._close_conn() elif self.length is not None: self.length -= len(result) + if not self.length: + self._close_conn() return result def peek(self, n=-1): @@ -687,6 +689,8 @@ class HTTPResponse(io.BufferedIOBase): self._close_conn() elif self.length is not None: self.length -= len(result) + if not self.length: + self._close_conn() return result def _read1_chunked(self, n): diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index f9da4927f682..015a3d1e872f 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -1503,11 +1503,14 @@ class ExtendedReadTest(TestCase): resp = self.resp self._verify_readline(self.resp.readline, self.lines_expected) - def _verify_readline(self, readline, expected): + def test_readline_without_limit(self): + self._verify_readline(self.resp.readline, self.lines_expected, limit=-1) + + def _verify_readline(self, readline, expected, limit=5): all = [] while True: # short readlines - line = readline(5) + line = readline(limit) if line and line != b"foo": if len(line) < 5: self.assertTrue(line.endswith(b"\n")) @@ -1515,6 +1518,7 @@ class ExtendedReadTest(TestCase): if not line: break self.assertEqual(b"".join(all), expected) + self.assertTrue(self.resp.isclosed()) def test_read1(self): resp = self.resp @@ -1534,6 +1538,7 @@ class ExtendedReadTest(TestCase): break all.append(data) self.assertEqual(b"".join(all), self.lines_expected) + self.assertTrue(resp.isclosed()) def test_read1_bounded(self): resp = self.resp @@ -1545,15 +1550,22 @@ class ExtendedReadTest(TestCase): self.assertLessEqual(len(data), 10) all.append(data) self.assertEqual(b"".join(all), self.lines_expected) + self.assertTrue(resp.isclosed()) def test_read1_0(self): self.assertEqual(self.resp.read1(0), b"") + self.assertFalse(self.resp.isclosed()) def test_peek_0(self): p = self.resp.peek(0) self.assertLessEqual(0, len(p)) +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 + + class ExtendedReadTestChunked(ExtendedReadTest): """ Test peek(), read1(), readline() in chunked mode diff --git a/Misc/NEWS.d/next/Library/2023-12-16-01-10-47.gh-issue-113199.oDjnjL.rst b/Misc/NEWS.d/next/Library/2023-12-16-01-10-47.gh-issue-113199.oDjnjL.rst new file mode 100644 index 000000000000..d8e0b1731d1e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-16-01-10-47.gh-issue-113199.oDjnjL.rst @@ -0,0 +1,3 @@ +Make ``http.client.HTTPResponse.read1`` and +``http.client.HTTPResponse.readline`` close IO after reading all data when +content length is known. Patch by Illia Volochii.