为啥这个 SPDY SYN_STREAM 样本的标头显然未压缩?

Posted

技术标签:

【中文标题】为啥这个 SPDY SYN_STREAM 样本的标头显然未压缩?【英文标题】:Why are the headers of this SPDY SYN_STREAM sample apparently uncompressed?为什么这个 SPDY SYN_STREAM 样本的标头显然未压缩? 【发布时间】:2015-02-11 18:52:52 【问题描述】:

我正在试验 SPDY 协议,偶然发现了a sample of SPDY protocol(可以使用“attachment”链接下载)。

这是我的看法:

    在 Wireshark 1.12.2(或更高版本)中打开 pcapng 文件 右键单击任何 SSL/TLS 帧,然后转到 Protocol Preferences -> RSA keys list... 点击新建,输入IP地址0.0.0.0,端口443,协议spdy和this key file的路径, 右键单击任何 SPDY 帧,转到 Protocol Preferences -> Uncompress SPDY headers 以禁用 SPDY header 解压缩 转到第 45 帧,观察“SPDY: SYN_STREAM”层中,突出显示“Header Block”后,下面的十六进制转储是可读的

根据 SPDY 规范,this should be compressed。为什么我可以看到这个?有没有办法在 SPDY 协议中禁用标头压缩?我是否以错误的方式使用 Wireshark?

【问题讨论】:

【参考方案1】:

关于规范

你链接的草稿是这样写的:

名称/值标头块的全部内容是使用 zlib 压缩的。连接上一个方向上的所有名称值对都有一个 zlib 流。 SPDY 在每个压缩帧之间使用 SYNC_FLUSH。

实施说明:可以调整压缩引擎以支持速度或大小。优化大小会增加内存使用和 CPU 消耗。由于标头块通常很小,因此实现者可能希望将压缩引擎的窗口大小从默认的 15 位(32 KB 窗口)减小到更像 11 位(2 KB 窗口)。确切的设置由压缩器选择,解压器可以使用任何设置。

它不强制执行任何压缩级别。事实上,你可以使用完全不压缩的 zlib,这是 zlib 格式支持的:

Level 0 实际上根本不进行压缩,实际上稍微扩展了数据以生成 zlib 格式(它不是输入的逐字节复制)。

关于样品

我联系了示例的作者。原来他正在使用 nginx 进行实验。在他提供的文档中,nginx是这样配置的:

 # SPDY
 server 
     listen       443 ssl spdy;
     server_name  localhost;
     ssl_certificate      cert.pem;
     ssl_certificate_key  key.pem;
     ssl_session_cache    shared:SSL:1m;
     ssl_session_timeout  5m;
     ssl_ciphers  DES-CBC3-SHA;
     ssl_prefer_server_ciphers  on;
     location / 
         root   html;
         index  index.html index.htm;
     

但是,nginx 文档指出必须明确指定标头压缩:

Syntax: spdy_headers_comp level;
Default : spdy_headers_comp 0;

设置标题压缩级别。 [...] 特殊值 0 关闭标头压缩。

这意味着很可能没有为实验启用标头压缩。

我的结论

是的,您可以在 SPDY 中禁用标头压缩,但您必须保持 zlib 格式的压缩级别为 0 您正在正确使用 Wireshark。您使用的示例是使用 0 压缩级别创建的

【讨论】:

嗯,谢谢,这听起来有道理,但零压缩不应该像任何其他压缩级别一样解压缩吗?我知道 Wireshark 可能存在某种错误,但我可以用任何其他语言编写解压缩这种零压缩格式的代码吗? 看看这里:gist.github.com/anonymous/ae61c49e2f65b54534b9。无论如何,我更接近于接受这个答案。 我设法解压了它。以下是详细信息:reverseengineering.stackexchange.com/q/8616/4674

以上是关于为啥这个 SPDY SYN_STREAM 样本的标头显然未压缩?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 spdy 在 nginx 1.5.10 中不起作用?

为啥 Google.com 切换到 SPDY (HTTP/2+QUIC/35) 而不是 HTTP/2

为啥我必须在 AWS Application Load Balancer 中禁用 HTTP/2 以防止出现 ERR_SPDY_PROTOCOL_ERROR?

LIBSVM 对未训练类的样本给出相同的预测。为啥?

Node.js 中的 SPDY https.request()

为啥在图像分类的预处理步骤中按样本在 -1 和 1 之间缩放像素