Skip to content

Commit e5ab9e3

Browse files
[3.12] gh-112064: Fix incorrect handling of negative read sizes in HTTPResponse.read() (GH-128270) (#129396)
gh-112064: Fix incorrect handling of negative read sizes in `HTTPResponse.read()` (GH-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. (cherry picked from commit 4d0d24f) Co-authored-by: Yury Manushkin <[email protected]>
1 parent ea143e6 commit e5ab9e3

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

Lib/http/client.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ def read(self, amt=None):
472472
if self.chunked:
473473
return self._read_chunked(amt)
474474

475-
if amt is not None:
475+
if amt is not None and amt >= 0:
476476
if self.length is not None and amt > self.length:
477477
# clip the read to the "end of response"
478478
amt = self.length
@@ -590,6 +590,8 @@ def _get_chunk_left(self):
590590

591591
def _read_chunked(self, amt=None):
592592
assert self.chunked != _UNKNOWN
593+
if amt is not None and amt < 0:
594+
amt = None
593595
value = []
594596
try:
595597
while (chunk_left := self._get_chunk_left()) is not None:

Lib/test/test_httplib.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,25 @@ def test_chunked(self):
10781078
self.assertEqual(resp.read(), expected)
10791079
resp.close()
10801080

1081+
# Explicit full read
1082+
for n in (-123, -1, None):
1083+
with self.subTest('full read', n=n):
1084+
sock = FakeSocket(chunked_start + last_chunk + chunked_end)
1085+
resp = client.HTTPResponse(sock, method="GET")
1086+
resp.begin()
1087+
self.assertTrue(resp.chunked)
1088+
self.assertEqual(resp.read(n), expected)
1089+
resp.close()
1090+
1091+
# Read first chunk
1092+
with self.subTest('read1(-1)'):
1093+
sock = FakeSocket(chunked_start + last_chunk + chunked_end)
1094+
resp = client.HTTPResponse(sock, method="GET")
1095+
resp.begin()
1096+
self.assertTrue(resp.chunked)
1097+
self.assertEqual(resp.read1(-1), b"hello worl")
1098+
resp.close()
1099+
10811100
# Various read sizes
10821101
for n in range(1, 12):
10831102
sock = FakeSocket(chunked_start + last_chunk + chunked_end)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix incorrect handling of negative read sizes in :meth:`HTTPResponse.read
2+
<http.client.HTTPResponse.read>`. Patch by Yury Manushkin.

0 commit comments

Comments
 (0)