cargo 在 config 里换了中科大的源还是会超时?

不知道是不是移动网的锅。在换了中科大的 crates.io 反向 proxy 源后,cargo run 下载依赖项时依然随时超时和暂停。

下载失败后,cargo 会报这么个错误:

这个要怎么解

感觉无解,前天给 alacritty 扒 vendor 时就发现,即使照 help 设置了镜像,或者直接灌代理都一直报这个错误,最后重试无数次之后终于才扒完了 vendor :neutral_face:

这种情况还是建议按照通用的给命令行挂代理的办法吧,详细去科学上网板块讨论

我联通的用中科大镜像没问题,你可以试试 rustcc 的镜像,有点慢不过能用。

[source.crates-io]
replace-with = "rustcc"

[source.rustcc]
registry = "https://code.aliyun.com/rustcc/crates.io-index.git"

感谢大家的回复。

这个方法确实可用,只是需要不停 Ctrl + C 中断下载:rofl:

貌似还是不能用… 不过还是很感谢你的回复。


其实相比而言,我更关心的是奇怪的报错信息。为什么不是直接报超时,而是说收到了 HTTP/0.9 这么远古的协议

去网上搜索了下,貌似 cargo 使用的是 curl 来下载 crates 包裹。那么问题可能出在 curl 库本身。

去翻了下 curl 在 GitHub 的更改信息。发现 HTTP/0.9 早已在 2019 年的一次提交中被默认禁用。在不加参数的情况下 curl 不再允许建立这样的连接。

这应该是导致下载不成功的直接原因。由于 curl 默认的安全机制,加上 cargo 也许没有为收到 HTTP/0.9 这种远古协议的可能做过处理,便直接扔出了建立不了连接的错误。

问题来了。为什么连接会被降级成 HTTP/0.9?或者说,为什么会超时?

我决定使用 curl 命令测试究竟:

curl -Lv https://mirrors.ustc.edu.cn/crates.io-index/ro/ck/rocksdb

上面这串命令,是用来模拟 cargo 利用 curl 下载附件包的情况。

在前几次运行命令时,curl 可以顺利地完成请求。

* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=mirrors.ustc.edu.cn
*  start date: Feb  3 03:57:40 2020 GMT
*  expire date: May  3 03:57:40 2020 GMT
*  subjectAltName: host "mirrors.ustc.edu.cn" matched cert's "mirrors.ustc.edu.cn"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x557928bfac40)
> GET /crates.io-index/ro/ck/rocksdb HTTP/2
> Host: mirrors.ustc.edu.cn
> user-agent: curl/7.69.0
> accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200 
< server: openresty
< date: Mon, 23 Mar 2020 02:17:12 GMT
< content-type: application/octet-stream
< content-length: 16529
< last-modified: Thu, 14 Nov 2019 16:45:11 GMT
< etag: "5dcd8497-4091"
< accept-ranges: bytes
< 
{"name":"rocksdb","vers":"0.0.1","deps":[],"cksum":"4933b4db381e16de0c15f6fb2b4ddbcb70751badbeae4e066d84fa1b71862b2b","features":{},"yanked":false}
{"name":"rocksdb","vers":"0.0.2","deps":[],"cksum":"6c555656de7a3253832bdabf5e6f1b3089ed41be9eb79427c29605360d6724d0","features":{},"yanked":false}
{"name":"rocksdb","vers":"0.0.3","deps":[],"cksum":"69143cee6c3dde25c53fd20b94c20a7261300ff497616247c0f8f09195f06c25","features":{},"yanked":false}

...
---以下太长的内容截掉了。避免刷屏---

但是,在我重复执行大概 3 次命令后,curl 的请求便疑似被丢包处理了:

pokon548@localhost:~/Programming/Original/hello-rocket> curl -Lv https://mirrors.ustc.edu.cn/crates.io-index/ro/ck/rocksdb > test.log
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 202.141.176.110:443...
* Connected to mirrors.ustc.edu.cn (202.141.176.110) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:02 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:03 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:04 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:05 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:06 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:07 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:08 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:09 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:10 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:11 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:12 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:13 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:14 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:15 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:16 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:17 --:--  0     0    0     0    0     0      0      0 --:--:--  0:00:18 --:--:--     0^C
pokon548@localhost:~/Programming/Original/hello-rocket>

在 Client Hello 之后,curl 无论如何都得不到应答。
现象和国内奇妙的国际网络优化因素丢包效果一致。也和 cargo 一段时间后无论如何都下载不到依赖包的行为一致。
故猜测,是优化因素导致请求失败。

由于这种奇妙的丢包因素是和请求联系在一起的。一旦有了这种丢包,响应地址的请求会暂时失效一小会儿(大概是十分钟左右)。决定换个包再试试效果:

pokon548@localhost:~/Programming/Original/hello-rocket> curl -Lv https://mirrors.ustc.edu.cn/crates.io-index/ro/ck/rock
*   Trying 202.141.176.110:443...
*   Trying 2001:da8:d800:95::110:443...
* Immediate connect fail for 2001:da8:d800:95::110: 网络不可达
* Connected to mirrors.ustc.edu.cn (202.141.176.110) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use h2
* Server certificate:
*  subject: CN=mirrors.ustc.edu.cn
*  start date: Feb  3 03:57:40 2020 GMT
*  expire date: May  3 03:57:40 2020 GMT
*  subjectAltName: host "mirrors.ustc.edu.cn" matched cert's "mirrors.ustc.edu.cn"
*  issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
*  SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55659b171c40)
> GET /crates.io-index/ro/ck/rock HTTP/2
> Host: mirrors.ustc.edu.cn
> user-agent: curl/7.69.0
> accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200 
< server: openresty
< date: Mon, 23 Mar 2020 02:33:27 GMT
< content-type: application/octet-stream
< content-length: 166
< last-modified: Sun, 21 Apr 2019 08:45:07 GMT
< etag: "5cbc2d93-a6"
< accept-ranges: bytes
< 
{"name":"rock","vers":"0.0.0-alpha.0","deps":[],"cksum":"8615735ff851d3e2ba9cec53788834b8ecfd8e27654fbeb85e022da439498823","features":{},"yanked":false,"links":null}
* Connection #0 to host mirrors.ustc.edu.cn left intact

又是如此。
在连续执行第四次 curl 命令时,请求慢了一刻才传达到 curl 这里。
连续第六次后,curl 再也没能收到请求。

pokon548@localhost:~/Programming/Original/hello-rocket> curl -Lv https://mirrors.ustc.edu.cn/crates.io-index/ro/ck/rock
*   Trying 202.141.176.110:443...
* Connected to mirrors.ustc.edu.cn (202.141.176.110) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
^C

只能被迫 Ctrl + C 中断连接。

可以确定,是 cargo 在请求连接的过程中受到丢包处理,导致请求失败。
而且这种处理貌似是针对内容的。不管我用什么镜像源,都会出现同样的优化现象。

所以:

  • 加密 SNI 赶快安排上啊(会暴露请求 URL)
  • 请移动 / 神秘因素不要 http/1.0 降级干扰请求(1.0 及其以下版本无法保证传输未被修改。因此可被用来搞事)

综上,看来只能根据苏姐的建议来了:sweat_smile:

本主题在最后一个回复创建后60分钟后自动锁定。不再允许添加新回复。