mirror of
https://github.com/python/cpython.git
synced 2025-08-19 08:11:46 +00:00
[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 4d0d24f6e3
)
Co-authored-by: Yury Manushkin <manushkin@gmail.com>
This commit is contained in:
parent
ea143e67b3
commit
e5ab9e3740
3 changed files with 24 additions and 1 deletions
|
@ -472,7 +472,7 @@ class HTTPResponse(io.BufferedIOBase):
|
||||||
if self.chunked:
|
if self.chunked:
|
||||||
return self._read_chunked(amt)
|
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:
|
if self.length is not None and amt > self.length:
|
||||||
# clip the read to the "end of response"
|
# clip the read to the "end of response"
|
||||||
amt = self.length
|
amt = self.length
|
||||||
|
@ -590,6 +590,8 @@ class HTTPResponse(io.BufferedIOBase):
|
||||||
|
|
||||||
def _read_chunked(self, amt=None):
|
def _read_chunked(self, amt=None):
|
||||||
assert self.chunked != _UNKNOWN
|
assert self.chunked != _UNKNOWN
|
||||||
|
if amt is not None and amt < 0:
|
||||||
|
amt = None
|
||||||
value = []
|
value = []
|
||||||
try:
|
try:
|
||||||
while (chunk_left := self._get_chunk_left()) is not None:
|
while (chunk_left := self._get_chunk_left()) is not None:
|
||||||
|
|
|
@ -1078,6 +1078,25 @@ class BasicTest(TestCase):
|
||||||
self.assertEqual(resp.read(), expected)
|
self.assertEqual(resp.read(), expected)
|
||||||
resp.close()
|
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
|
# Various read sizes
|
||||||
for n in range(1, 12):
|
for n in range(1, 12):
|
||||||
sock = FakeSocket(chunked_start + last_chunk + chunked_end)
|
sock = FakeSocket(chunked_start + last_chunk + chunked_end)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix incorrect handling of negative read sizes in :meth:`HTTPResponse.read
|
||||||
|
<http.client.HTTPResponse.read>`. Patch by Yury Manushkin.
|
Loading…
Add table
Add a link
Reference in a new issue