为什么 HTTP Upgrade: header 在 Apache 中同时包含 h2 和 h2c?

Why does the HTTP Upgrade: header contain both h2 and h2c in Apache?

为什么 HTTP 升级:header 在 Apache 中同时包含 h2 和 h2c?

我认为您只能 运行 HTTP/2 明文变体,(h2c)。

为什么还包括选项h2?因为它只能从 TLS 访问,对吗?

编辑,最后一个问题:

通过 HTTP,Apache 会忽略升级到 h2 的请求,但通常会公布它。

Client (HTTP/1.1 without the upgrade header) => Apache (Sends Upgrade: h2, h2c)

Client (HTTP/1.1 with Upgrade: h2) => Apache (Ignores request to upgrade,
                                              and responds back with HTTP/1.1)

在 HTTP 上,Apache 尊重升级到 h2c,它通常会宣传它:)

Client (HTTP/1.1 without the upgrade header) => Apache (Sends Upgrade: h2, h2c)

Client (HTTP/1.1 with Upgrade: h2c) => Apache (Respects request, sends
                                               101 Switching Protocols)
                                       Apache (Uses HTTP/2 Cleartext)

通过 HTTPS,Apache 忽略所有升级到 h2 和 h2c 的请求。 Apache 还通过 HTTPS 发送 h2c。这是为什么?

以上所有行为是否符合标准?

因为您可以升级到 h2h2c。是的,如果您最初使用 HTTPS,前者会自动协商,但如果您不使用,那么可以有效地说,如果您切换到 HTTPS,则可以使用 h2。您还可以发送回 301/302 重定向,这将有效地将您重定向到 HTTPS 等 h2 但是由于浏览器不使用升级机制,您可能不能假设发送应用程序将使用这些?

对我来说一个更大的问题是为什么升级机制存在!正如我认为您暗示的那样,如果您可以使用 HTTPS,那么您将使用 HTTP/2,因此不需要升级机制。浏览器仅通过 HTTPS 支持 HTTP/2 的原因是它在 HTTP 上如此不可靠,因为中间件假设 HTTP/1 - 这意味着 h2c 的唯一用途是用于 non-browser 通信,您基本上可以控制端到端连接,因此可以跳过升级舞蹈并直接进入 h2c(也称为使用 HTTP/2 的“先验知识”方法)。如果客户端意外不支持 HTTP/2.

,则前言消息始终可用于拒绝 and/or 回退到 HTTP/1

与此同时,升级机制确实会导致真正的问题。例如,nginx 过去常常盲目转发它,即使它已经在使用 HTTP/2 给客户端。因此,如果后端 Apache 服务器看到 nginx 连接是 HTTP/1.1,然后建议 HTTP/2 然后 nginx 将其转发到浏览器,因为它已经在谈论 HTTP/2(对 nginx)而变得困惑. Safari 过去处理这个问题的方式非常糟糕,基本上会中断并拒绝显示该网站。是的,如果 Apache 在升级 header 时没有建议 h2,这可能就不会发生(这是你的问题的来源吗?)但从技术上讲,这是 nginx 的错。我不记得他们是否解决了这个问题,但我认为他们解决了。

无论如何,这已被 HTTP 工作组和 they are likely to remove the upgrade mechanism for the next update to the HTTP/2 spec 认可。

说到这里,我想知道 h2c 是否有很多用处?显然,不支持它的浏览器严重影响了它的使用,但正如我所说,这是一个很好的理由。它在 non-browser 上下文中使用很多吗?很难说,即使是这样,要求使用 HTTPS 会不会是一个额外的负担 and/or 更可靠?

编辑:回答您进一步的问题。

是的,所有这些都是正确的。

情况1:无法使用h2 HTTP,因此无法通过升级header使用。由于这个原因,h2 是否应该在升级 header 中是有争议的,正如你所指出的,它没有在允许升级 header 的 IANA 注册表中列出。我的理解是这是为了通过相同的传输协议升级连接,而 h2 仍然是通过 HTTP over TCP,所以从技术上讲是通过相同的传输协议,它确实需要 HTTP 所以确实需要一个新的连接(通常是不同的端口)所以绝对拉伸升级的定义!

情况 2:是的,这就是应该发生的情况。

案例 3:有争议但我认为在技术上是正确的。我称之为降级而不是升级,但升级机制实际上是一种“我支持你可能喜欢的不同协议”机制,而不是“升级到更好的协议”header。与情况 1 类似,这可能需要一个新的连接,因此这是否真的符合预期使用的升级机制仍然存在争议。

正如我所说,所有这些都是相当不相关的,或者很快就会,因为它将从 HTTP/2 规范中删除。