Apache HTTP2 h2c 模式无法正常工作

Posted

技术标签:

【中文标题】Apache HTTP2 h2c 模式无法正常工作【英文标题】:Apache HTTP2 h2c mode not working properly 【发布时间】:2020-06-06 06:52:46 【问题描述】:

我想在 apache 上启用 h2c 模式,所以我可以使用 HTTP2.0 协议。在我的虚拟主机配置中,我包含了以下行:

Protocols h2c http/1.1

我也关注了advise to disable prefork,但它没有按预期工作。

目前我在 Ubuntu 上使用 apache 2.4.29。

案例1)curl请求http2升级

$ curl -vs --http2 http://domain1.com
* Rebuilt URL to: http://domain1.com/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to domain1.com (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: domain1.com
> User-Agent: curl/7.58.0
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
> 
< HTTP/1.1 101 Switching Protocols
< Upgrade: h2c
< Connection: Upgrade
* Received 101
* 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=28
* Connection state changed (MAX_CONCURRENT_STREAMS updated)!
< HTTP/2 200 
< date: Sun, 00 Jan 1900 00:00:00 GMT
< server: Apache/2.4.29 (Ubuntu)
< last-modified: Fri, 29 Mar 2019 13:52:29 GMT
< etag: W/"2aa6-5853bfb4c71ac"
< accept-ranges: bytes
< content-length: 10918
< vary: Accept-Encoding
< content-type: text/html
< 
.... [snip website code] ....

案例2)curl直接使用http2

$ curl -vs --http2-prior-knowledge http://domain1.com
* Rebuilt URL to: http://domain1.com/
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to domain1.com (127.0.0.1) port 80 (#0)
* 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 0x5604f1cb1580)
> GET / HTTP/2
> Host: domain1.com
> User-Agent: curl/7.58.0
> Accept: */*
> 
* http2 error: Remote peer returned unexpected data while we expected SETTINGS frame.  Perhaps, peer does not support HTTP/2 properly.

如您所见,案例 1 正在按预期工作,但案例 2 没有返回站点。为什么会这样?是不是因为 Apache 限制直接使用 HTTP2.0 而没有安全性?

希望你能给我一个答案,因为我不知道为什么现在事情不工作了。

【问题讨论】:

也许这可能是卷曲问题,但我会自己尝试一次并将结果提供给您,我们可以知道为什么会发生这种情况。 确保你在 apache 中启用了 mod_http2,如果你使用的是 ubuntu/debian,还要安装 libnghttp2-dev 包。或者,如果您安装了 centos/rhel/fedora,请确保安装了 libnghttp2-devel 软件包。 我认为您应该在该命令中使用 https。 【参考方案1】:

我想我已经找到了答案,而且我认为这是最新 Apache 版本中的一个错误。如果我只在虚拟主机中启用 h2c,错误仍然存​​在,但如果我在默认虚拟主机 (000-default.conf) 上启用它,一切似乎都工作正常。

我测试过的另一个可行的解决方案是通过修改 mods-enabled/http2.load 文件在每个虚拟主机中启用协议 h2 和 h2c:

LoadModule http2_module /usr/lib/apache2/modules/mod_http2.so

<IfModule http2_module>
   Protocols h2 h2c http/1.1
</IfModule>

上述任何选项似乎都可以使系统在协议协商和先验知识的情况下按预期工作。

【讨论】:

奇数。你介意在这里提出一个问题:github.com/icing/mod_h2/issues 吗?主要的 Apache http2 开发人员通常对错误非常敏感,然后希望会修复它。 我在找到答案的同一天就做到了。 Bug 64171

以上是关于Apache HTTP2 h2c 模式无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

Go http2 和 h2c

Apache如何启用HTTP2?

springboot搭建http2服务器和h2c服务器 h2 的http/https 请求服务器

Netty HTTP2 帧转发/代理 - 管道配置问题

h2csmuggler:一款隐蔽性极强的HTTP2明文通信工具

Nginx 是不是支持以明文形式从 http/1.1 升级 http/2 (h2c)