Rust in Everything
基于 reqwest 0.13.5

动手

前面各部分读的是 reqwest 怎么把 hyper-util、tower-http 和 TLS 库拼成一个客户端。这一部分反过来,自己拼一遍:不用 reqwest,也不用 hyper-rustls,直接在 hyper-util 的 legacy Client 下面接一个自己写的 HTTPS 连接器,上面加总超时、重定向和 JSON。目的不是造一个能替代 reqwest 的库,而是看清哪些能力是 hyper-util 白给的,哪些要自己写,以及 reqwest 在每一项上又多做了什么。

  1. mini-client:295 行的库,依赖 hyper 1.12.0、hyper-util 0.1.21、tokio-rustls 0.26.6(ring)和 url。连接器把 TCP 交给 HttpConnector,HTTPS 再套一层 TLS,并把 ALPN 的结果用 negotiated_h2 告诉连接池;一个 tokio::time::timeout 包住重定向循环和读 body,最多跟 5 次重定向,跨源时去掉 Authorization 等四个头;JSON 解码失败时错误里带响应体的前 200 字节。7 个测试打到 testsrv:HTTPS 下 HTTP/2 和 HTTP/1.1 各三个请求只用一条连接,300 ms 的总超时在卡响应头和卡响应体时都在 302 到 303 ms 触发。最后一张表列出它比 reqwest 少的东西,每一行链到讲那一块的页面。
flowchart TB
  send["send 加总超时"] --> follow["重定向循环"]
  follow --> legacy["legacy Client"]
  legacy --> pool["连接池"]
  pool -- 没有连接 --> conn["HttpsConnector"]
  conn --> tcp["HttpConnector"]
  conn --> tls["tokio-rustls"]
  tls --> alpn["negotiated_h2"]

读这一页之前,最好先读过一次请求和连接器,知道 reqwest 的连接器在 legacy Client 下面处于什么位置;legacy Client 本身见 hyper 卷的 legacy Client。

💬 关联讨论

发起讨论
加载中...