Skip to content

Commit baa3d77

Browse files
committed
requests: Add readinto to BodyStream for mip compatibility.
BodyStream now implements readinto() so mip can stream downloads via response.raw without allocating intermediate buffers. Signed-off-by: Pablo Ventura <pablogventura@gmail.com>
1 parent 6372c93 commit baa3d77

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

python-ecosys/requests/requests/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ def read(self, n=-1):
1717
raise ValueError("Connection closed before Content-Length satisfied")
1818
return data
1919

20+
def readinto(self, buf):
21+
if self._remaining == 0:
22+
return 0
23+
n = len(buf)
24+
if n > self._remaining:
25+
n = self._remaining
26+
got = self._sock.readinto(memoryview(buf)[:n])
27+
self._remaining -= got
28+
if not got:
29+
raise ValueError("Connection closed before Content-Length satisfied")
30+
return got
31+
2032
def close(self):
2133
self._sock.close()
2234

python-ecosys/requests/test_requests.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ def readline(self):
1919
def read(self, size=-1):
2020
return self._read_buffer.read(size)
2121

22+
def readinto(self, buf):
23+
data = self._read_buffer.read(len(buf))
24+
n = len(data)
25+
buf[:n] = data
26+
return n
27+
2228
def close(self):
2329
pass
2430

@@ -227,6 +233,22 @@ def test_raw_incremental_content_length():
227233
install_mock_socket()
228234

229235

236+
def test_raw_readinto_content_length():
237+
socket.socket = lambda *a, **k: Socket(
238+
read_data=b"HTTP/1.1 200 OK\r\nContent-Length: 10\r\n\r\nabcdefghij"
239+
)
240+
response = requests.request("GET", "http://example.com")
241+
buf = bytearray(3)
242+
result = b""
243+
while True:
244+
n = response.raw.readinto(buf)
245+
if n == 0:
246+
break
247+
result += buf if n == 3 else buf[:n]
248+
assert result == b"abcdefghij"
249+
install_mock_socket()
250+
251+
230252
TESTS = (
231253
test_simple_get,
232254
test_get_auth,
@@ -241,6 +263,7 @@ def test_raw_incremental_content_length():
241263
test_chunked_response_raises,
242264
test_raw_open_before_content,
243265
test_raw_incremental_content_length,
266+
test_raw_readinto_content_length,
244267
)
245268

246269

0 commit comments

Comments
 (0)