HTTP/2 是无状态协议吗?

Is HTTP/2 a stateless protocol?

据我了解,HTTP/2 附带一个名为 HPACK 的有状态 header 压缩。它不会改变 HTTP 协议的无状态语义吗? Web 应用程序将 HTTP/2 视为无状态协议是否安全?最后,HTTP/2 是否与现有的负载均衡器兼容?

HTTP/2 是无状态的。

原始的HTTP是一个无状态的协议,这意味着每个请求消息都可以被孤立地理解。这意味着每个请求都需要携带尽可能多的细节,因为服务器需要为该请求提供服务,而服务器不必存储以前请求的大量信息和元数据。

由于 HTTP/2 没有改变这种范式,它必须以同样的方式工作,无状态。

official RFCs 也可以清楚地看到它。表示:

The Hypertext Transfer Protocol (HTTP) is an application-level protocol for distributed, collaborative, hypermedia information systems. It is a generic, stateless, protocol which can be used for many tasks...

HTTP/2 的定义说:

This specification describes an optimized expression of the semantics of the Hypertext Transfer Protocol (HTTP), referred to as HTTP version 2 (HTTP/2)... This specification is an alternative to, but does not obsolete, the HTTP/1.1 message syntax. HTTP's existing semantics remain unchanged.

结论

HTTP/2 协议在设计上是无状态的,因为与原始 HTTP 相比语义保持不变。


混乱可能来自何处

HTTP/2 连接是 TCP 连接之上的应用层协议 运行(顺便说一句,没有什么能阻止你使用 ,例如,这是可能的,但是 UDP未使用,因为它不是“可靠的传输”)。不要将它与会话层和传输层混合。 HTTP 协议在设计上是无状态的。 通过加密 SSL/TLS 连接的 HTTP,也没有改变此声明,因为 HTTPS 中的 S 与传输有关,而不是协议本身。

HPACK, Header Compression for HTTP/2, is a compression format especially crafted for HTTP/2 headers, and it is being specified in a separate internet draft。它不会改变 HTTP/2 本身,所以它不会改变语义。

在关于 HPACK 的部分 RFC for HTTP/2 中,他们声明:

Header compression is stateful. One compression context and one decompression context are used for the entire connection.

这就是 HPACK's RFC 的原因:

2.2. Encoding and Decoding Contexts

To decompress header blocks, a decoder only needs to maintain a dynamic table (see Section 2.3.2) as a decoding context. No other dynamic state is needed.

When used for bidirectional communication, such as in HTTP, the encoding and decoding dynamic tables maintained by an endpoint are completely independent, i.e., the request and response dynamic tables are separate.


HPACK reduces the length of header field encoding by exploiting the redundancy inherent in protocols like HTTP. The ultimate goal of this is to reduce the amount of data that is required to send HTTP requests or responses.

HPACK 实现不可能是完全无状态的,因为编码表和解码表完全独立,必须由端点维护。

同时,还有一些库试图解决 HPACK 问题,例如无状态事件驱动的 HPACK 编解码器 CASHPACK:

An HPACK implementation cannot be completely stateless, because a dynamic table needs to be maintained. Relying on the assumption that HTTP/2 will always decode complete HPACK sequences, statelessness is achieved using an event-driven API.

现代 HTTP,包括 HTTP/2,是一种有状态协议。过去的 HTTP 是无状态的。

许多 HTTP/2 组件正是有状态的定义。

没有任何理性的人会阅读 HTTP/2 RFC 并认为它是无状态的。错误的“HTTP 是无状态的”旧时教条是错误的,并不代表 HTTP 的当前现实。

这是有状态 HTTP/1 和 HTTP/2 组件的有限但并非详尽的列表:

  • Cookies,(由 RFC 命名为“HTTP 状态管理机制”)
  • HTTPS,存储密钥因此状态
  • HTTP 身份验证需要状态
  • 网络存储
  • HTTP 缓存是有状态的
  • 流标识符的真正目的是状态
  • Header 建立流标识符的块是有状态的。
  • 引用流标识符的帧是有状态的
  • Header HTTP RFC 明确表示有状态的压缩是有状态的。
  • 机会加密是有状态的。
HTTP/2 RFC 的

Section 5.1 是 HTTP/2 标准定义的 有状态 机制的一个很好的例子。

Is it safe for web applications to consider HTTP/2 as a stateless protocol?

HTTP/2 是有状态协议,但这并不意味着您的 HTTP/2 应用程序不能是无状态的。您可以选择不对无状态 HTTP/2 应用程序使用某些有状态功能,方法是仅使用 HTTP/2 功能的一个子集。

Cookie 和其他一些有状态机制,或不太明显的有状态机制,是后来的 HTTP 添加。 HTTP 1 is said to be stateless 虽然在实践中我们使用标准化的状态机制。 与HTTP/1.0 不同,HTTP/2 在其标准 中定义了有状态组件,因此是有状态的。特定的 HTTP/2 应用程序可以使用 HTTP/2 功能的子集来保持无状态。

需要状态的现有应用程序,甚至是 HTTP 1 应用程序,如果尝试无状态地使用它们,将会中断。如果禁用 cookie,则可能无法登录某些 HTTP/1.1 网站,从而破坏应用程序。假设特定的 HTTP 1 应用程序不使用状态可能是不安全的。 HTTP/2 也不例外。在 Netscape 于 1994 年发明 cookie 和 HTTPS 之前,http 可以被认为是无状态的。

最后跟我说一遍:

HTTP/2 是有状态协议。