- 需要使用连续的两个 CRLF 来判断 header 部分的结束,而不是使用头部字节设置 header 的长度,这就造成解析器需要扫描 TCP 内容流去查找分割点,性能下降。
- chunked transfer-encoding 中每个 chunk 的长度使用 hex 标识,但是长度信息还是使用 CRLF 来终结,这个也降低了性能。
其实很多其他的协议,如电信短信系统的 SGIP/SMPP 和 BS 的 WebSocket 协议,它们对协议包大小都采用固定长度前导字节的方式。
下面对比看看 WebSocket 协议:
每个 frame 的头部第一字节标明该 frame 的总长度,1-126 字节的长度就够用了,如果 frame 长度超过 126 字节,则使用 127 标明下面的双字节 UInt16 代表 frame 的总长度,128 代表下面的 UInt64 代表 frame 的总长度。
可以看出,http 协议其实可以重新设计
- header 如果是 UInt8 只有 256 byte,肯定是不够的,而使用 UInt16 标明自己的长度,共有 64K 的长度足够 header 使用了,考虑到Request URL, Referer, Cookie 和 User-Agent 都是较长的串,header 总长度一般应该超过 256,因此就直接设定 header 长度标识为固定的 UInt16BE 即可
- chunked transfer-ecoding 可以完全照搬 WebSocket 协议。
虽然 http 的设计对于 parse 效率考虑不周,但是由于它的广泛使用,其设计已经成为事实上的标准,虽毒害万千,但也是无法改变的现实了。