Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d20e774

Browse files
committed
Issue #16298: In HTTPResponse.read(), close the socket when there is no Content-Length and the incoming stream is finished.
Patch by Eran Rundstein.
2 parents 3050541 + 084daa2 commit d20e774

4 files changed

Lines changed: 42 additions & 2 deletions

File tree

Lib/http/client.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,9 @@ def readinto(self, b):
536536
self.length -= n
537537
if not self.length:
538538
self.close()
539+
else:
540+
if not n:
541+
self.close()
539542
return n
540543

541544
def _read_next_chunk_size(self):

Lib/test/test_httplib.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ def test_bad_status_repr(self):
175175
self.assertEqual(repr(exc), '''BadStatusLine("\'\'",)''')
176176

177177
def test_partial_reads(self):
178-
# if we have a lenght, the system knows when to close itself
178+
# if we have a length, the system knows when to close itself
179179
# same behaviour than when we read the whole thing with read()
180180
body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText"
181181
sock = FakeSocket(body)
@@ -187,7 +187,7 @@ def test_partial_reads(self):
187187
self.assertTrue(resp.isclosed())
188188

189189
def test_partial_readintos(self):
190-
# if we have a lenght, the system knows when to close itself
190+
# if we have a length, the system knows when to close itself
191191
# same behaviour than when we read the whole thing with read()
192192
body = "HTTP/1.1 200 Ok\r\nContent-Length: 4\r\n\r\nText"
193193
sock = FakeSocket(body)
@@ -203,6 +203,38 @@ def test_partial_readintos(self):
203203
self.assertEqual(bytes(b), b'xt')
204204
self.assertTrue(resp.isclosed())
205205

206+
def test_partial_reads_no_content_length(self):
207+
# when no length is present, the socket should be gracefully closed when
208+
# all data was read
209+
body = "HTTP/1.1 200 Ok\r\n\r\nText"
210+
sock = FakeSocket(body)
211+
resp = client.HTTPResponse(sock)
212+
resp.begin()
213+
self.assertEqual(resp.read(2), b'Te')
214+
self.assertFalse(resp.isclosed())
215+
self.assertEqual(resp.read(2), b'xt')
216+
self.assertEqual(resp.read(1), b'')
217+
self.assertTrue(resp.isclosed())
218+
219+
def test_partial_readintos_no_content_length(self):
220+
# when no length is present, the socket should be gracefully closed when
221+
# all data was read
222+
body = "HTTP/1.1 200 Ok\r\n\r\nText"
223+
sock = FakeSocket(body)
224+
resp = client.HTTPResponse(sock)
225+
resp.begin()
226+
b = bytearray(2)
227+
n = resp.readinto(b)
228+
self.assertEqual(n, 2)
229+
self.assertEqual(bytes(b), b'Te')
230+
self.assertFalse(resp.isclosed())
231+
n = resp.readinto(b)
232+
self.assertEqual(n, 2)
233+
self.assertEqual(bytes(b), b'xt')
234+
n = resp.readinto(b)
235+
self.assertEqual(n, 0)
236+
self.assertTrue(resp.isclosed())
237+
206238
def test_host_port(self):
207239
# Check invalid host_port
208240

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,7 @@ Paul Rubin
10161016
Sam Ruby
10171017
Demur Rumed
10181018
Audun S. Runde
1019+
Eran Rundstein
10191020
Rauli Ruohonen
10201021
Jeff Rush
10211022
Sam Rushing

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ Core and Builtins
108108
Library
109109
-------
110110

111+
- Issue #16298: In HTTPResponse.read(), close the socket when there is no
112+
Content-Length and the incoming stream is finished. Patch by Eran
113+
Rundstein.
114+
111115
- Issue #15872: Fix 3.3 regression introduced by the new fd-based shutil.rmtree
112116
that caused it to not ignore certain errors when ignore_errors was set.
113117
Patch by Alessandro Moura and Serhiy Storchaka.

0 commit comments

Comments
 (0)