流程图描述了当提供 HTTP URL 时 curl 内部执行的一些步骤和决策。包括主机名、协议和端口号。
该流程图忽略了代理、身份验证考虑和 unix 域套接字的使用,以使事情更简单。
网址
第一步当然是从 URL 中提取主机名部分。URL 中的主机名可以是纯 IP 地址,也可以是名称。如果 URL 中未提供数字 IPv4 或 IPv6 地址,curl 会检查主机名是否使用 IDN(国际域名)提供,如果是,则将名称转换为punycode ,以便继续处理。
现有连接
给定协议、主机名和端口号,curl 会检查是否存在可用的连接。优先使用现有连接,因为这是启动新传输的最快方式。连接重用基于提供的名称而不是 IP 地址,因此如果已有可用连接,curl 可以跳过这一步。
–连接到
当尝试连接到主机时,curl 首先检查是否选择了任何技巧,例如此选项使得 curl 实际上在被要求连接到主机 A 时解析主机名 B。
alt-svc
curl 可能拥有之前传输的 alt-svc 缓存。它本质上是将特定 HTTP 版本和主机名映射到另一个 HTTP 版本和主机名,并在一定时间内完成。这可以将主机名 A 更改为主机名 B。
-解决
此选项使用一个或多个用户提供的给定主机名的 IP 地址填充 DNS 缓存。
DNS缓存
在 curl 将主机名解析为一组 IP 地址之前,它会检查 DNS 缓存中是否已包含该信息,因为这通常比再次请求该数据要快得多。条目通常只会在缓存中保留一分钟,直到被清除。
解析
当 curl 解析主机名时,它需要 A、AAAA 和HTTPS DNS 记录数据。A 和 AAAA 提供了尝试连接的 IP 地址列表,HTTPS 字段提供了 HTTP 版本信息、端口号、ECH 配置以及其他可能的信息。
高速传输系统
curl 可能还带有 HSTS 缓存,这是另一种映射,用于在需要将普通 HTTP 访问内部升级为 HTTPS 的情况下使用。这会更改要使用的协议和默认端口号。
赛车
根据上述步骤确定的 curl 应尝试使用的 IP 版本和 HTTP 版本,curl 会启动连接竞争,可能会进行相当多的并行连接尝试,每次尝试都会比前一次延迟一点。
- 首先尝试通过 IPv6 进行 QUIC 连接
- QUIC 通过 IPv4 进行连接尝试第二次
- IPv6 上的 TCP 连接尝试排在第三
- 通过 IPv4 进行 TCP 连接尝试是第四次
当然,如果其中任何一个任务无法完成或失败,就会立即跳过,并开始下一个任务。如果前一个任务在一定时间内没有完成,则每个任务都可能启动一个新的任务。
第一个成功连接到主机的竞争者获胜,其他尝试将被迅速丢弃。

TLS握手
如果协议是 HTTPS(选择 HTTP/3 时始终为 HTTPS),则 TLS 握手在 TCP 连接建立后执行。对于 HTTP/3,TLS 握手集成在 QUIC 连接设置中。
TLS 握手可以使 curl 重用现有会话、决定 ALPN、使用 ECH 并发送早期数据。
会话 ID/票证处理也是缓存 curl 保留的,允许更快地重新连接到之前连接过的主机。
联系
一旦 curl 建立了可用的连接,它就会开始发送 HTTP 请求,从而开始传输。
图表

原文: https://daniel.haxx.se/blog/2025/10/16/chart-which-host-which-protocol/