]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-113199: Make read1() and readline() of HTTPResponse close IO after reading...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 18 Dec 2023 20:34:15 +0000 (21:34 +0100)
committerGitHub <noreply@github.com>
Mon, 18 Dec 2023 20:34:15 +0000 (20:34 +0000)
(cherry picked from commit 41336a72b90634d5ac74a57b6826e4dd6fe78eac)

Co-authored-by: Illia Volochii <illia.volochii@gmail.com>
Lib/http/client.py
Lib/test/test_httplib.py
Misc/NEWS.d/next/Library/2023-12-16-01-10-47.gh-issue-113199.oDjnjL.rst [new file with mode: 0644]

index 87bca4d76aba924909f489bda616e2bc9223b3d6..1ee22989ae118865be34a97909a4cb8c835997e4 100644 (file)
@@ -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):
index f9da4927f682e93b312e11499345d0e6faed5088..015a3d1e872ff267d5683863749896f1542484dc 100644 (file)
@@ -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 (file)
index 0000000..d8e0b17
--- /dev/null
@@ -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.