You could try setting stream=True
, then aborting a request when your time or size limits are exceeded while you read the data in chunks.
As of requests
release 2.3.0 the timeout applies to streaming requests too, so all you need to do is allow for a timeout for the initial connection and each iteration step:
r = requests.get(..., stream=True, timeout=initial_timeout)
r.raise_for_status()
if int(r.headers.get('Content-Length')) > your_maximum:
raise ValueError('response too large')
size = 0
start = time.time()
for chunk in r.iter_content(1024):
if time.time() - start > receive_timeout:
raise ValueError('timeout reached')
size += len(chunk)
if size > your_maximum:
raise ValueError('response too large')
# do something with chunk
Adjust the timeout as needed.
For requests
releases < 2.3.0 (which included this change) you could not time out the r.iter_content()
yield; a server that stops responding in the middle of a chunk would still tie up the connection. You'd have to wrap the above code in an additional timeout function to cut off long-running responses early.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…