【问题标题】:Why does the HTTP Upgrade: header contain both h2 and h2c in Apache?为什么 HTTP Upgrade: 标头在 Apache 中同时包含 h2 和 h2c?
【发布时间】:2021-08-07 12:13:32
【问题描述】:

为什么 HTTP Upgrade: 标头在 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。这是为什么呢?

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

【问题讨论】:

    标签: apache http-headers


    【解决方案1】:

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

    对我来说一个更大的问题是为什么存在升级机制!正如我认为您暗示的那样,如果您可以使用 HTTPS,那么您将使用 HTTP/2,因此不需要升级机制。浏览器仅通过 HTTPS 支持 HTTP/2 的原因是它在 HTTP 上是如此不可靠,因为中间盒假定 HTTP/1 - 这意味着 h2c 的唯一用途是用于非浏览器通信,您基本上可以控制端到端连接所以可以跳过升级舞步直接使用 h2c(也就是使用 HTTP/2 的“先验知识”方法)。如果客户端意外不支持 HTTP/2,前言消息始终可用于拒绝和/或回退到 HTTP/1。

    与此同时,升级机制确实会引起实际问题。例如,nginx 过去常常盲目地转发它,即使它已经使用 HTTP/2 到客户端。因此,如果后端 Apache 服务器看到 nginx 连接是 HTTP/1.1,然后建议使用 HTTP/2,那么 nginx 会将其转发到浏览器,浏览器会感到困惑,因为它已经在与 HTTP/2(到 nginx)通信。 Safari 过去处理这个问题真的很糟糕,基本上破坏并拒绝显示该站点。是的,如果 Apache 没有在升级标头中建议 h2,这可能不会发生(这是您的问题的根源吗?)但从技术上讲,这里是 nginx 的错误。我不记得他们是否解决了这个问题,但我认为他们做到了。

    不管怎样,这已经得到了 HTTP 工作组和they are likely to remove the upgrade mechanism for the next update to the HTTP/2 spec 的认可。

    虽然我们在做,但我想知道 h2c 是否有很多用处?显然,不支持它的浏览器严重影响了它的使用,但正如我所说,这是一个很好的理由。它在非浏览器上下文中使用得很多吗?很难说,即使要求使用 HTTPS 是否会成为额外的负担和/或更可靠?

    编辑:回答您的其他问题。

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

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

    案例 2:是的,这是应该发生的。

    案例 3:有争议,但我认为在技术上是正确的。我将其称为降级而不是升级,但升级机制实际上是“我支持您可能喜欢的不同协议”机制,而必然是“升级到更好的协议”标头。与案例 1 类似,这可能需要一个新的连接,所以这是否真的符合预期使用的升级机制是有争议的。

    正如我所说,所有这些都无关紧要,或者很快就会发生,因为它将从 HTTP/2 规范中删除。

    【讨论】:

    • iana.org/assignments/http-upgrade-tokens/… 在 upgrade: 标头中不包含普通的 h2。
    • 为什么只有 Apache 包含 Upgrade: 标头而没有 101 交换协议?
    • Apache 使用 h2 通过 HTTP 发送 Upgrade: 标头
    • 升级是可以支持其他协议的通知。如果要升级,则由客户端使用 101 启动此操作。有趣的是,这种误解曾经破坏过 Node:github.com/nodejs/node/issues/4334
    • 那么,可以发送 Upgrade: without 101 status 对吗?
    猜你喜欢
    • 2015-11-04
    • 1970-01-01
    • 2012-11-07
    • 2016-10-16
    • 1970-01-01
    • 1970-01-01
    • 2012-06-27
    • 1970-01-01
    • 2011-01-27
    相关资源
    最近更新 更多