如果不自己解决问题,我无法完全用 curl 做我需要的事情,但有一些发现可供其他人分享:
首先,作为一个编写良好的 TCP 客户端,curl 会从上到下尝试 DNS 列表中的主机,直到连接成功。从那时起,即使它返回一些更高级别的错误(例如 SSL 错误或 HTTP 500),它也会使用该主机。这对所有重大案件都有好处。
较新的 curl 版本的 curl 命令行具有--retry
和--retry-all-errors
- 但libcurl
不幸的是,在 中没有这样的东西。该功能目前正在增强,截至 2021 年 7 月 14 日,还没有任何版本将枚举所有 DNS 主机,直到有一个返回 HTTP 200。相反,已发布的 curl 版本(我尝试了 7.76 和 7.77)将总是用同一个主机重试。但是每晚构建(2021-07-14)确实枚举了所有 DNS 主机。以下是两次重试和三个不存在的主机的行为方式(注意,如果任何主机返回 HTTP 5xx,则会发生重试):
$ ./src/curl http://nohost.sureno --trace - --retry 2 --retry-all-errors
== Info: Trying 192.168.1.112:80...
== Info: connect to 192.168.1.112 port 80 failed: No route to host
== Info: Trying 192.168.1.113:80...
== Info: connect to 192.168.1.113 port 80 failed: No route to host
== Info: Trying 192.168.1.114:80...
== Info: connect to 192.168.1.114 port 80 failed: No route to host
== Info: Failed to connect to nohost.sureno port 80 after 9210 ms: No route to host
== Info: Closing connection 0
curl: (7) Failed to connect to nohost.sureno port 80 after 9210 ms: No route to host
Warning: Problem (retrying all errors). Will retry in 1 seconds. 2 retries
Warning: left.
== Info: Hostname nohost.sureno was found in DNS cache
== Info: Trying 192.168.1.112:80...
== Info: connect to 192.168.1.112 port 80 failed: No route to host
== Info: Trying 192.168.1.113:80...
== Info: connect to 192.168.1.113 port 80 failed: No route to host
== Info: Trying 192.168.1.114:80...
== Info: connect to 192.168.1.114 port 80 failed: No route to host
== Info: Failed to connect to nohost.sureno port 80 after 9206 ms: No route to host
== Info: Closing connection 1
curl: (7) Failed to connect to nohost.sureno port 80 after 9206 ms: No route to host
Warning: Problem (retrying all errors). Will retry in 2 seconds. 1 retries
这种行为对 libcurl 的用户非常有帮助,但不幸的是,这些重试标志目前没有映射到curl_easy_setopt
. 结果,如果你给--libcurl
命令行你将看不到任何与重试相关的代码