Preserve chunked argument in urlopen() retry
MODIFY
dummyserver/testcase.py
dummyserver/testcase.py
@@ -15,8 +15,13 @@ from dummyserver.proxy import ProxyHandler
def consume_socket(sock, chunks=65536):
- while not sock.recv(chunks).endswith(b"\r\n\r\n"):
- pass
+ consumed = bytearray()
+ while True:
+ b = sock.recv(chunks)
+ consumed += b
+ if b.endswith(b"\r\n\r\n"):
+ break
+ return consumed
class SocketDummyServerTestCase(object):

MODIFY
src/urllib3/connectionpool.py
src/urllib3/connectionpool.py
@@ -839,6 +839,7 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
timeout=timeout,
pool_timeout=pool_timeout,
release_conn=release_conn,
+ chunked=chunked,
body_pos=body_pos,
**response_kw
)

MODIFY
test/with_dummyserver/test_chunked_transfer.py
test/with_dummyserver/test_chunked_transfer.py
# -*- coding: utf-8 -*-
from urllib3 import HTTPConnectionPool
-from dummyserver.testcase import SocketDummyServerTestCase
+from urllib3.util.retry import Retry
+from dummyserver.testcase import SocketDummyServerTestCase, consume_socket
class TestChunkedTransfer(SocketDummyServerTestCase):
@@ -100,3 +101,24 @@ class TestChunkedTransfer(SocketDummyServerTestCase):
host_headers = [x for x in header_lines if x.startswith(b"host")]
assert len(host_headers) == 1
+
+ def test_preserve_chunked_on_retry(self):
+ self.chunked_requests = 0
+
+ def socket_handler(listener):
+ for _ in range(2):
+ sock = listener.accept()[0]
+ request = consume_socket(sock)
+ if b"Transfer-Encoding: chunked" in request.split(b"\r\n"):
+ self.chunked_requests += 1
+
+ sock.send(b"HTTP/1.1 404 Not Found\r\n\r\n")
+ sock.close()
+
+ self._start_server(socket_handler)
+ with HTTPConnectionPool(self.host, self.port) as pool:
+ retries = Retry(total=1, raise_on_status=False, status_forcelist=[404])
+ pool.urlopen(
+ "GET", "/", chunked=True, preload_content=False, retries=retries
+ )
+ assert self.chunked_requests == 2

Preserve chunked argument in urlopen() retry (#1715)