服务器和 docker 镜像上 CURL 命令的 HTTP 版本

服务器和 docker 镜像上 CURL 命令的 HTTP 版本

当我从 docker 容器执行 CURL 调用时curl https://example.com,出现错误curl: (92) HTTP/2 stream 0 was not closed cleanly: HTTP_1_1_REQUIRED (err 13)。但是,当我从运行 docker 容器的主机服务器 (RHEL) 运行相同的命令时,它工作正常。

所以,我在docker容器的命令中添加了--http1.1,然后它就可以正常工作了。但是当我在主机服务器上使用 --http1.1 运行相同的命令时,出现错误curl: option --http1.1: is unknown

  1. 调用时curl 如何获取http 版本?我们是否可以定义默认使用特定版本的任何设置?
  2. 为什么 --http1.1 不在服务器上工作,但在 docker 容器中工作?

服务器上的 Curl 版本是 7.29.0。 docker 容器上的 Curl 版本是 7.64.0

答案1

长话短说:修复您的网络服务器。

很长的故事

您的 HTTP 服务器一定做错了什么!curl不会尝试进行 HTTP/2 连接,除非服务器建议它可以这样做。

所以,问题的答案是:

调用时curl 如何获取http 版本?

它监听服务器声称支持的内容。

我们是否可以定义任何设置来默认使用特定版本?

是的,这是内置于 HTTP 协议中的(响应的第一行);实际上,考虑到您正在使用 TLS (https://…),这应该已经由客户端使用 TLS/ALPN 中的协议标识符明确定义h2,并且服务器将响应它支持该h2协议,即它同意它确实可以对话 HTTP/2。

否则,curl将会不是使用 HTTP/2。

您可以自己检查您的 HTTP 服务器的不当行为!

$ # https://stackoverflow.com does support HTTP/2
$ curl --verbose --output /dev/null https://stackoverflow.com
* Connected to stackexchange.com (151.101.65.69) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN: server accepted h2
* Using HTTP2, server supports multiplexing
> GET / HTTP/2

所以,在这里你可以看到,作为协议 IDcurl提供 h2给服务器,服务器实际上必须在curl使用 HTTP/2 之前接受它。

将其与过时的网络服务器的行为以及curl反应进行比较:

$ # https://www.gnu.org only supports HTTP/1.1, in 2023.
$ curl --verbose --output /dev/null https://www.gnu.org/software/grub/manual/grub/html_node/normal.html
* Connected to www.gnu.org (2001:470:142:5::116) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted http/1.1
> GET /software/grub/manual/grub/html_node/normal.html HTTP/1.1

curl因此,您的 Web 服务器必须在 TLS 连接建立中告知它支持 HTTP/2(通过信号h2支持),但实际上并不支持它。

为什么 --http1.1 不在服务器上工作,但在 docker 容器中工作?

您的主机服务器curl非常旧;该选项是在 curl 版本 7.33.0 中添加的,距今已有近 10 年。

相关内容