首页 > 解决方案 > 如何让 curl 重试?

问题描述

我正在尝试让 curl 重试,如下所示:

curl -vvv --retry 100 -H "Authorization: SNIP" "localhost:8086/foo"

localhost:8086/foo被配置为总是发回一个“坏”的 HTTP 状态码。我试过发送 503、429 和 408,但在所有情况下,curl 只尝试一次。以下是一些示例日志:

*   Trying 127.0.0.1:8086...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 8086 (#0)
> GET /foo HTTP/1.1
> Host: localhost:8086
> User-Agent: curl/7.68.0
> Accept: */*
> Authorization: SNIP
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 408 Request Time-out
< Expires: 0
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate
< X-XSS-Protection: 1; mode=block
< Pragma: no-cache
< X-Frame-Options: DENY
< Date: Sun, 01 Nov 2020 21:27:00 GMT
< Connection: keep-alive
< X-Content-Type-Options: nosniff
< Content-Length: 0
< 
* Connection #0 to host localhost left intact

如您所见,日志确认 curl 收到 408 但 curl 立即返回。它不会再重试 100 次。

我是否需要指定其他--retry内容才能使其正常工作?

这是我的卷曲版本:

curl -V
curl 7.68.0 (x86_64-pc-linux-gnu) libcurl/7.68.0 OpenSSL/1.1.1f zlib/1.2.11 brotli/1.0.7 libidn2/2.2.0 libpsl/0.21.0 (+libidn2/2.2.0) libssh/0.9.3/openssl/zlib nghttp2/1.40.0 librtmp/2.3
Release-Date: 2020-01-08
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets

标签: curl

解决方案


我在主机上运行 curl 7.68.0。Daniel Stenberg 在对我的问题的评论中指出,7.66.0+ 有一个错误,它破坏了至少状态 408 的重试功能。它似乎对 503 工作正常,所以我可以切换到那个。

我还在运行一个 docker 容器(debian/10.5),其中最新的 curl 稳定包是 7.64.0。在这个版本中,408、429 和 503 似乎都被破坏了。我通过按照以下步骤将 libcurl 和 curl 升级到下一个可用的 debian 包(bullseye)解决了这个问题,在撰写本文时它是 7.72.0:

  1. 从适当的镜像下载 curl 。
  2. 从适当的镜像下载 libcurl 。
  3. 安装 libcurl:dpkg -i libcurl4_7.72.0-1_amd64.deb
  4. 安装卷曲:dpkg -i curl_7.72.0-1_amd64.deb

现在 `curl --retry 100 localhost/foo" 在遇到 503 状态时有效。


推荐阅读