为 Twisted 代理请求的响应体设置截止时间
将代理端点的连接超时与一个 Deferred 截止时间结合使用,后者同时覆盖读取小型响应体的过程。
ProxyAgent 可能很快连接成功,随后却无限期等待响应体。它的代理端点连接超时并不描述之后这段等待。
在构建 agent 时于端点上设置连接上限。对于下面的公开 HTTP 请求,如果允许使用公共中间人,可以用 HTTP 代理列表中未经验证的候选地址替换该地址:
endpoint = TCP4ClientEndpoint(reactor, 'proxy.example', 8080,
timeout=5)
agent = ProxyAgent(endpoint, reactor=reactor)
对于打算读入内存的小型响应,在添加截止时间之前先把读取响应体纳入 Deferred 链:
from twisted.web.client import readBody
d = agent.request(b'GET', b'http://example.com/')
d.addCallback(readBody)
d.addTimeout(10, reactor)
d.addCallback(lambda body: print(len(body)))
d.addErrback(lambda failure: print(failure.getErrorMessage()))
该片段假设应用已经拥有自己的 reactor 和配置好的 agent。ProxyAgent 的请求 Deferred 会给出响应对象;readBody 返回响应体的 Deferred。在回调中返回它,链就会同样等待该操作。
位置很关键。Twisted 的 addTimeout 作用于它之前安装的回调所代表的工作。若之后再添加响应体读取器,描述的将是另一条边界。在这种安排下,计时器在调用 addTimeout 时启动,并覆盖该链中挂起的请求与响应体工作。
对于很大或没有边界的响应体,应使用流式消费者,并以同样的方式表示其完成。客户端一侧的截止时间只限制应用等待多久;它不会重新配置代理自身的上游连接超时。