对于经由普通 HTTP 代理的 ssl::stream<tcp::socket>,先使用它的原始传输层,再让它执行目标端 TLS:

auto& transport = tlsStream.next_layer();
  1. 把该传输层连接到代理主机和端口。在没有配置代理凭据、且目标是允许访问的公共 HTTPS 站点时,HTTP 代理列表 提供了候选端点;请确认该候选允许所请求的隧道。
  2. 发送 CONNECT,并在其中写明目标 authority,例如 api.example:443,同时在明文传输层上解析完整的响应头。2xx 表示隧道建立成功;拒绝则仍然只是一条 HTTP 代理响应。
  3. 配置目标主机名、所需的 SNI、信任根和证书对端校验,然后在 tlsStream 上启动客户端握手。
  4. TLS 成功后,应用层读写都通过 SSL 流进行。此时若直接读取下一层,就会绕过 TLS 处理。

把 HTTP 解析器中剩余的缓冲数据带入下一阶段。Asio 提供带缓冲的握手重载;丢弃解析器持有的尾部数据,可能丢失已经从套接字读出的字节。

在这个简单类型中,next_layer 和 lowest_layer 都到达 TCP。包装层更多时两者可能不同,因此应选择承载代理实际线协议的接口。HTTPS 代理会再加一层 TLS,不属于这条明文 CONNECT 流程。

相关文章