深入理解httpx中的请求与响应扩展机制

深入理解httpx中的请求与响应扩展机制

httpx A next generation HTTP client for Python. 🦋 httpx 项目地址: https://gitcode.com/gh_mirrors/ht/httpx

扩展机制概述

在httpx库中,请求(Request)和响应(Response)对象都提供了一个名为"extensions"的无类型空间,开发者可以在这里添加额外的信息。这种设计主要用于处理那些可能不适用于所有传输方式,且不适合直接放入httpx简化请求/响应模型的功能特性。

扩展机制的核心价值在于它提供了一种灵活的方式来传递和处理与请求/响应相关的元数据,而不会污染标准HTTP协议定义的字段。这种设计既保持了核心API的简洁性,又为高级用例提供了足够的扩展能力。

请求扩展详解

1. 超时控制扩展

超时控制是httpx中一个非常实用的功能,它实际上是通过请求扩展实现的。这种设计确保超时设置能够在整个调用栈中传递。

client = httpx.Client()
response = client.get(
    "https://www.example.com",
    extensions={"timeout": {"connect": 5.0}}  # 设置连接超时为5秒
)

超时扩展支持多种类型的超时设置:

  • connect: 连接建立超时
  • read: 读取响应超时
  • write: 发送请求超时
  • pool: 连接池等待超时

虽然可以直接使用扩展来设置超时,但更推荐使用httpx提供的高级timeout API,它提供了更友好的接口。

2. 请求追踪扩展

请求追踪扩展(trace)是一个非常强大的调试工具,它允许开发者监控底层httpcore传输层内部的事件流。

def log(event_name, info):
    print(event_name, info)

client = httpx.Client()
response = client.get("https://www.example.com/", extensions={"trace": log})

追踪事件分为三种类型:

  1. {event_type}.{event_name}.started: 事件开始
  2. {event_type}.{event_name}.complete: 事件完成
  3. {event_type}.{event_name}.failed: 事件失败

当前支持的事件类型包括:

  • 连接建立相关事件
  • HTTP/1.1协议事件
  • HTTP/2协议事件

对于异步代码,传递给trace的处理函数必须是async def定义的异步函数。

3. SNI主机名扩展

SNI(Server Name Indication)主机名扩展(sni_hostname)用于指定SSL证书验证时使用的主机名,这在需要直接连接到IP地址而非域名时特别有用。

headers = {"Host": "www.example.com"}
extensions = {"sni_hostname": "www.example.com"}
response = client.get(
    "https://185.199.108.153/path",
    headers=headers,
    extensions=extensions
)

4. 目标扩展

目标扩展(target)允许开发者覆盖HTTP请求中的标准路径部分,支持一些特殊场景:

  1. 发送包含非标准转义字符的路径
  2. 通过绝对URI发送正向代理请求
  3. 使用CONNECT方法建立隧道代理连接
  4. 服务器范围的OPTIONS请求
# 发送包含字面量'^'的路径
extensions = {"target": b"/test^path"}
response = httpx.get("https://www.example.com", extensions=extensions)

响应扩展详解

1. HTTP版本信息

http_version扩展提供了服务器使用的HTTP协议版本信息,如b"HTTP/1.1"。对于HTTP/2连接,该值固定为b"HTTP/2"

2. 原因短语

reason_phrase扩展包含了HTTP响应中的原因短语,如b"OK"。需要注意的是,HTTP/2及更高版本不再在协议中包含原因短语。

3. 流ID

当使用HTTP/2协议时,stream_id扩展可以获取响应所在数据流的ID。

4. 网络流扩展

network_stream扩展为处理HTTP CONNECT和Upgrade请求提供了底层网络访问能力,是构建代理、WebSocket等高级功能的基础。

网络流接口提供的方法包括:

  • read(): 从网络读取数据
  • write(): 向网络写入数据
  • close(): 关闭连接
  • start_tls(): 启动TLS加密
  • get_extra_info(): 获取额外网络信息
# 获取客户端和服务端地址信息
network_stream = response.extensions["network_stream"]
client_addr = network_stream.get_extra_info("client_addr")
server_addr = network_stream.get_extra_info("server_addr")

最佳实践与注意事项

  1. 扩展的稳定性:扩展机制提供的功能在不同版本中可能有所变化,特别是追踪事件的具体集合。如果依赖特定事件,建议固定依赖版本。

  2. 性能考虑:频繁使用追踪扩展可能会影响性能,建议仅在调试时启用。

  3. 安全性:使用目标扩展时,必须确保构造的请求仍然是有效的HTTP请求,避免潜在问题。

  4. 异步兼容性:在异步环境中使用追踪扩展时,必须使用异步处理函数。

  5. 网络流生命周期:访问网络流的SSL信息时,必须确保底层连接仍然处于打开状态。

通过合理使用httpx的扩展机制,开发者可以构建出功能强大且灵活的HTTP客户端应用,满足各种复杂场景的需求。

httpx A next generation HTTP client for Python. 🦋 httpx 项目地址: https://gitcode.com/gh_mirrors/ht/httpx

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫骅弘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值