【问题标题】:python requests keep connection alive for indefinite timepython请求使连接无限期保持活动状态
【发布时间】:2019-12-03 17:22:58
【问题描述】:

我正在尝试运行一个 python 脚本,该脚本在一定间隔内调用外部 API(我只有读取权限),该 API 使用基于 cookie 的身份验证:调用/auth 端点最初设置会话cookie 然后用于在进一步的请求中进行身份验证。

至于我的问题:由于身份验证基于活动会话,因此一旦连接断开,cookie 就无效,因此必须重新启动。根据我的阅读,requests 基于urllib3,默认情况下保持连接处于活动状态。然而,经过几次测试后,我注意到在某些情况下,连接无论如何都会断开。

我使用了来自requests 模块的Session 对象,并测试了断开连接需要多长时间,如下所示:

from requests import session
import logging
import time import time, sleep

logging.basicConfig(level=logging.DEBUG)

def tt(interval):
    credentials = {"username":"user","password":"pass"}
    s = Session()
    r = s.post("https://<host>:<port>/auth", json=credentials)
    ts = time()
    while r.status_code is 200:
        r = s.get("https://<host>:<port>/some/other/endpoint")
        sleep(interval)
    return time() - ts # Seconds until connection drop

可能不是找出这一点的最佳方法,但我让该函数运行两次,一次以 1 秒的间隔运行,然后以 1 分钟的间隔运行。两者都运行了大约一个小时,直到我不得不手动停止执行。

但是,当我在 while 循环中交换两行时,这意味着在初始 POST /auth 请求之后有 1 分钟的延迟,以下 GET 请求失败并出现 401 Unauthorized 和此消息已预先记录:

DEBUG:urllib3.connectionpool:Resetting dropped connection: <host>

由于在我的 prod 脚本中请求的间隔可能从几分钟到几个小时不等,我必须事先知道这些会话保持活动的时间以及该规则是否存在一些例外情况(例如,如果没有,则断开连接在最初的POST /auth 发出一段时间后的请求)。

那么,requests 或更确切地说是urllib3 保持连接活动多长时间,是否可以无限期延长该时间?

或者是服务器而不是requests 断开了连接?

【问题讨论】:

    标签: python python-3.x python-requests urllib


    【解决方案1】:

    通过使用requests.Sessionkeep-alive is handled for you automatically

    在调用/auth 后持续轮询服务器的循环的第一个版本中,服务器不会因为随后发生的GET 而断开连接。在第二个版本中,睡眠间隔可能超过了服务器配置为保持连接打开的时间。

    根据 API 的服务器配置,响应标头可能包含 Keep-Alive 标头,其中包含有关连接保持打开的最短时间的信息。 HTTP/1.0 指定此信息包含在 Keep-Alive 标头的 timeout 参数中。您可以使用此信息来确定距离服务器断开连接还有多长时间。

    HTTP/1.1 中,默认使用持久连接并且不使用Keep-Alive 标头,除非服务器显式实现它以实现向后兼容性。由于这种差异,客户端无法立即确定连接的确切超时时间,因为它可能仅作为服务器端配置存在。

    保持连接打开的关键是定期继续轮询。您使用的时间间隔必须小于服务器配置的连接超时时间。

    要指出的另一件事是,以这种方式人为地无限期延长会话的长度会使人更容易受到session fixation attacks 的攻击。您可能需要考虑添加偶尔会重新建立会话的逻辑,以最大程度地降低此类攻击的风险。

    【讨论】:

    • 感谢您提供有关该漏洞的提示!顺便说一句,如果未在响应中设置 Keep-Alive 标头,除了反复试验之外,是否有可能获得确切的时间间隔直到超时?
    • @AhmedBajra 我认为从客户的角度来看,这可能是您没有响应标头的唯一选择。我更新了我的答案以反映这一点。
    猜你喜欢
    • 2012-02-06
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 2016-03-23
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多