深入理解httpx中的请求与响应扩展机制
httpx A next generation HTTP client for Python. 🦋 项目地址: 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})
追踪事件分为三种类型:
{event_type}.{event_name}.started
: 事件开始{event_type}.{event_name}.complete
: 事件完成{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请求中的标准路径部分,支持一些特殊场景:
- 发送包含非标准转义字符的路径
- 通过绝对URI发送正向代理请求
- 使用CONNECT方法建立隧道代理连接
- 服务器范围的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")
最佳实践与注意事项
-
扩展的稳定性:扩展机制提供的功能在不同版本中可能有所变化,特别是追踪事件的具体集合。如果依赖特定事件,建议固定依赖版本。
-
性能考虑:频繁使用追踪扩展可能会影响性能,建议仅在调试时启用。
-
安全性:使用目标扩展时,必须确保构造的请求仍然是有效的HTTP请求,避免潜在问题。
-
异步兼容性:在异步环境中使用追踪扩展时,必须使用异步处理函数。
-
网络流生命周期:访问网络流的SSL信息时,必须确保底层连接仍然处于打开状态。
通过合理使用httpx的扩展机制,开发者可以构建出功能强大且灵活的HTTP客户端应用,满足各种复杂场景的需求。
httpx A next generation HTTP client for Python. 🦋 项目地址: https://gitcode.com/gh_mirrors/ht/httpx
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考