https://github.com/python/cpython/commit/4d0d24f6e3dff2864007c3cfd1cf7d49c6ee5317
commit: 4d0d24f6e3dff2864007c3cfd1cf7d49c6ee5317
branch: main
author: Yury Manushkin <[email protected]>
committer: Eclips4 <[email protected]>
date: 2025-01-28T11:37:32Z
summary:
gh-112064: Fix incorrect handling of negative read sizes in
`HTTPResponse.read()` (#128270)
The parameter `amt` of `HTTPResponse.read()`, which could be a negative integer,
has not been handled before and led to waiting for the connection to close
for `keep-alive connections`. Now, this has been fixed, and passing negative
values
to `HTTPResponse().read()` works the same as passing `None` value.
files:
A Misc/NEWS.d/next/Library/2024-12-26-11-00-03.gh-issue-112064.mCcw3B.rst
M Lib/http/client.py
M Lib/test/test_httplib.py
diff --git a/Lib/http/client.py b/Lib/http/client.py
index fab90a0ba4eb83..33a858d34ae1ba 100644
--- a/Lib/http/client.py
+++ b/Lib/http/client.py
@@ -472,7 +472,7 @@ def read(self, amt=None):
if self.chunked:
return self._read_chunked(amt)
- if amt is not None:
+ if amt is not None and amt >= 0:
if self.length is not None and amt > self.length:
# clip the read to the "end of response"
amt = self.length
@@ -590,6 +590,8 @@ def _get_chunk_left(self):
def _read_chunked(self, amt=None):
assert self.chunked != _UNKNOWN
+ if amt is not None and amt < 0:
+ amt = None
value = []
try:
while (chunk_left := self._get_chunk_left()) is not None:
diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py
index 7a7ec555a2dbbb..75b748aee05940 100644
--- a/Lib/test/test_httplib.py
+++ b/Lib/test/test_httplib.py
@@ -1092,6 +1092,25 @@ def test_chunked(self):
self.assertEqual(resp.read(), expected)
resp.close()
+ # Explicit full read
+ for n in (-123, -1, None):
+ with self.subTest('full read', n=n):
+ sock = FakeSocket(chunked_start + last_chunk + chunked_end)
+ resp = client.HTTPResponse(sock, method="GET")
+ resp.begin()
+ self.assertTrue(resp.chunked)
+ self.assertEqual(resp.read(n), expected)
+ resp.close()
+
+ # Read first chunk
+ with self.subTest('read1(-1)'):
+ sock = FakeSocket(chunked_start + last_chunk + chunked_end)
+ resp = client.HTTPResponse(sock, method="GET")
+ resp.begin()
+ self.assertTrue(resp.chunked)
+ self.assertEqual(resp.read1(-1), b"hello worl")
+ resp.close()
+
# Various read sizes
for n in range(1, 12):
sock = FakeSocket(chunked_start + last_chunk + chunked_end)
diff --git
a/Misc/NEWS.d/next/Library/2024-12-26-11-00-03.gh-issue-112064.mCcw3B.rst
b/Misc/NEWS.d/next/Library/2024-12-26-11-00-03.gh-issue-112064.mCcw3B.rst
new file mode 100644
index 00000000000000..e885add7b68c0f
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-12-26-11-00-03.gh-issue-112064.mCcw3B.rst
@@ -0,0 +1,2 @@
+Fix incorrect handling of negative read sizes in :meth:`HTTPResponse.read
+<http.client.HTTPResponse.read>`. Patch by Yury Manushkin.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]