为啥 curl 在 mac 上使用 HTTP/1.1 而不是 HTTP/2?

Posted

技术标签:

【中文标题】为啥 curl 在 mac 上使用 HTTP/1.1 而不是 HTTP/2?【英文标题】:Why is curl using HTTP/1.1 rather than HTTP/2 on mac?为什么 curl 在 mac 上使用 HTTP/1.1 而不是 HTTP/2? 【发布时间】:2017-12-08 22:51:53 【问题描述】:

据此https://curl.haxx.se/docs/http2.html

Since 7.47.0, the curl tool enables HTTP/2 by default for HTTPS connections.

用自制软件安装最新版本并检查:

curl --version
curl 7.54.1 (x86_64-apple-darwin15.6.0) libcurl/7.54.1 SecureTransport zlib/1.2.5

但在启用 HTTP2 的 URL 上运行 curl(例如使用 https://tools.keycdn.com/http2-test 进行测试)我得到:

curl -I http://www.google.co.uk 
HTTP/1.1 200 OK

curl --http2 -v http://www.google.co.uk
curl: (1) Unsupported protocol

知道为什么它使用 HTTP/1.1 而不是 HTTP/2 吗?

【问题讨论】:

【参考方案1】:

您可以构建 curl 以使用许多不同的 TLS/SSL 库之一,每个库都有略微不同的功能集,并为 curl 提供略微不同的条件。

您在问题中显示的 curl 将 SecureTransport 列为其构建使用的 TLS 库,即 macOS 本机 TLS 库。

安全传输根本没有为 curl 提供通过 TLS 协商 HTTP/2 的必要方法——或者至少它没有提供,因为我被告知最新版本现在支持 ALPN,因此未来的 curl 版本应该即使使用安全传输,也能够通过 TLS 执行 HTTP/2。

除了正确的 TLS 协商之外,curl 还需要使用 HTTP/2,这要归功于使用古老的 nghttp2 库,所以这是 curl 能够使用 HTTP/2 所需要的第二个依赖项。有了 nghttp2,即使 TLS 库无法正确协商 ALPN,curl 实际上也可以通过纯文本 HTTP 使用 HTTP/2。

修复?

后来的 macOS 版本提供了使用 libreSSL 构建的 curl,并且内置了 HTTP/2 支持。

如果您选择使用其他 TLS 库(例如 OpenSSL、GnuTLS 或 NSS)重建 curl,它现在已经可以通过 HTTPS 正常使用 HTTP/2。

【讨论】:

仅供参考,在 SecureTransport 中启用 HTTP/2 协商的功能是 SSLSetALPNProtocols。它适用于 ios 11+ 和 macOS 10.13+。 与此同时,Apple 已经切换,现在发布了使用 libressl 构建的 curl ... 哦。不知道那个。这……令人惊讶。【参考方案2】:

使用 MacOS Sierra,您可以使用 OpenSSL 而不是 SecureTransport 安装支持 HTTP2 的更新 curl。

    brew reinstall curl --with-openssl --with-nghttp2 brew link curl --force 重新启动终端 curl -V 应该返回如下内容:

curl 7.54.1 (x86_64-apple-darwin16.6.0) libcurl/7.54.1 OpenSSL/1.0.2l zlib/1.2.8 nghttp2/1.24.0 发布日期:2017-06-14 协议:dict 文件 ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 特性: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy

我应该注意到,MacOS 次要点更新有时会覆盖正在使用的 curl 版本。如果发生这种情况,只需重新运行 brew link curl --force 并重新启动终端即可切换回支持自制 HTTP2 的版本。

【讨论】:

旁注:macOS High Sierra 附带 curl 7.54.0,并且它支持内置 HTTP2。

以上是关于为啥 curl 在 mac 上使用 HTTP/1.1 而不是 HTTP/2?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Linux/Mac 中更新 PHP curl 扩展?

sh 在Mac上安装具有SFTP支持的cURL

mac 下curl的使用

为啥我不能在 Mac 上使用 python 更改 tkinter 按钮的背景颜色?

为啥在 Windows 上使用 Mechanize 访问 SSL 站点会失败,但在 Mac 上可以工作?

为啥我的网站在 Mac 上的 safari 上滚动过度?