2 回答

TA贡献1821条经验 获得超6个赞
这个问题的简短答案是:如果发生任何异常(包括KeyboardInterrupt和),请求将关闭连接SystemExit。
一个小 挖入请求的源代码显示,requests.get最终调用的HTTPAdapter.send方法(这是所有魔术发生)。
在该send方法内可以通过两种方式发出请求:分块或不分块。其中send我们执行要看的价值request.body和Content-Length标题:
chunked = not (request.body is None or 'Content-Length' in request.headers)
在请求主体为None或的情况下Content-Length,requests将使用以下高级urlopen方法urllib3:
if not chunked:
resp = conn.urlopen(
method=request.method,
url=url,
body=request.body,
# ...
)
该方法的finally块urllib3.PoolManager.urlopen具有在try块未成功执行的情况下处理关闭连接的代码:
clean_exit = False
# ...
try:
# ...
# Everything went great!
clean_exit = True
finally:
if not clean_exit:
# We hit some kind of exception, handled or otherwise. We need
# to throw the connection away unless explicitly told not to.
# Close the connection, set the variable to None, and make sure
# we put the None back in the pool to avoid leaking it.
conn = conn and conn.close()
release_this_conn = True
在响应可以分块的情况下,请求会降低一点并使用由提供的底层低层连接urllib3。在这种情况下,请求仍会处理异常,它使用try/except块执行此操作,该块在获取连接后立即开始,并以:
low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT)
try:
# ...
except:
# If we hit any problems here, clean up the connection.
# Then, reraise so that we can handle the actual exception.
low_conn.close()
raise
有趣的是,如果没有错误,则连接可能不会关闭,具体取决于您为组态连接池的方式urllib3。在成功执行的情况下,将连接放回连接池中(尽管我无法_put_conn在requests源代码中找到针对chunked的调用send,这可能是在chunked工作流程中的错误)。
添加回答
举报