【问题标题】:HTTP/2 behaviors with HTTP and HTTPSHTTP/2 行为与 HTTP 和 HTTPS
【发布时间】:2017-12-14 03:33:56
【问题描述】:

这个https://en.wikipedia.org/wiki/HTTP/2#Encryption

HTTP/2 是为 HTTP URI(即不加密)和 HTTPS URI(通过 TLS,需要 TLS 1.2 或更高版本)定义的。[25]

但在 Google 上测试我得到不同的结果:

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

curl --http2 -I https://www.google.co.uk
HTTP/2 200 

其他域也是如此。有什么解释吗?

【问题讨论】:

    标签: http https http2 http-1.1


    【解决方案1】:

    原因是所有浏览器出于各种原因决定仅在加密模式下支持 HTTP/2 (h2)。

    因此,大多数工具(库、网络服务器、cli 工具等)也专注于通过 ALPN 支持 HTTP/2 over TLS,并且通常不支持需要 HTTP 的未加密变体 (h2c)升级或具备有关 HTTP/2 的先验知识。

    在你的情况下 curl seems to support HTTP/2 upgrade requests,但谷歌网络服务器没有。

    【讨论】:

      【解决方案2】:

      HTTP/2 可以通过未加密的通道(称为 h2c)进行协商,但更复杂的是客户端如何知道服务器是否会理解相对较新的 HTTP/2 协议?此外,代理服务器在未加密发送时通常会遇到处理此类新协议的问题,但在发送加密时处理它们却很好(因为在这种情况下他们看不到它使用新协议)。

      对于加密连接,在发送第一个 HTTP 请求之前,HTTP/2(加密时称为 h2)作为 HTTPS 协商的一部分使用 ALPN 扩展(或它已替换的旧 NPN 扩展)进行协商。

      对于没有 HTTPS 协商的未加密连接,有两种选择:

      1. 假设服务器使用 HTTP/2 并立即开始使用 HTTP/2。这有点自以为是,但如果失败了,如果你退回到 HTTP/1,理论上会起作用。在许多方面,它类似于关于将 HTTPS 设为默认并回退到 HTTP 的讨论——它需要临界质量才能使这变得有价值。

      2. 将初始请求作为 HTTP/1 请求并使用 upgrade: h2c HTTP 标头(以及作为另一个 HTTP 标头的 base 64 HTTP/2 设置帧)发送。这会询问服务器我们是否可以切换到 HTTP/2 来处理下一个请求。服务器应该发送带有类似升级标头的 HTTP/1 响应,此时可以将下一个请求作为 HTTP/2 请求发送。这个过程在HTTP/2 spec in section 3.2中有详细说明。

      Curl 目前只支持这里详述的第二种方法:https://curl.haxx.se/docs/http2.html 所以不会直接讲 HTTP/2。如果您在详细模式下运行 curl -v,那么您应该会看到升级标头。

      但是none of the mainstream web browsers support HTTP/2 over unencrypted channels (h2c) 使 h2 成为事实上的标准 - 至少对于旨在供 Web 浏览器使用的面向公众的服务器而言。因此,许多 Web 服务器同样选择不去实现 h2c,因为它很少使用。见this page to see how few implementations support h2c。 Google 的服务器通常由 GFE(Google Front End)提供支持,您可以从该列表中看到仅支持 h2 而不是 h2c。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-14
        • 2018-12-30
        • 1970-01-01
        • 2011-03-09
        • 1970-01-01
        • 2011-09-15
        • 2019-04-28
        • 2015-04-07
        相关资源
        最近更新 更多