spdy3的名称/值块无法用python解压缩SOMETIMES

时间:2014-01-06 02:20:05

标签: python google-chrome zlib compression spdy

我正在为chrome构建一个spdy代理服务器。

当从chrome发送代理请求时,通常我会收到3帧:

  1. SETTINGS框架(正确解析)
  2. https'CONNECT请求的SYN_STREAM帧(也正确解析)
  3. 另一个SYN_STREAM帧,其名称/值块无法解压缩(解压缩数据时出错-3:不正确的标头检查)
  4. 最后一帧非常奇怪,因为我可以解析第一个同时具有名称/值块的SYN_STREAM。

    我一直试图解决这个问题2天,甚至将spdy版本从2改为3,但仍然无法解决。

    这是我的解压缩功能(Python 3.3):

    def decompress(buf):
        decompressor = zlib.decompressobj(zdict=DICT3)
        # DICT3 is the dictionary of spdy3 to decompress NV block
        return decompressor.decompress(buf)
    

    以下是日志的完整示例

    (1)2014-01-06 14:44:55,070 proxy           DEBUG: [49036176] on_read b'\x80\x03\x00\x04\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x03\xe8\x00\x00\x00\x07\x00\xa0\x00\x00\x80\x03\x00\x01\x00\x00\x00\xbf\x00\x00\x00\x01\x00\x00\x00\x00\x00\x008\xea\xe3\xc6\xa7\xc2\x02e%\x10\xb6\x82\x16\x08\\\xc0\xd4U\x90X\xa9\x97\x0c.&\xd8\xad\xe0\x89\x99\xdd\xd9\xdf\xcf\xcf\xd59\x04\xac\xb8 \x11\\l\xf1\x01\x04PbNfAb\xa5^r~\xae\x95\x89\x891@\x00\x81\x12\xb3\x15\xf6\x84\x8d\x9a\xa1r|\xf3\xab2sr\x12\xf5M\xf5\x0c\x144\xc23\xf3R\xf2\xcb\x8b\x15\xfcB\x14\xcc\xf4\x0c\xad\x15\xc2\xfd\xc3\xcdL4\x811\x06\x8c\xdf\xf0\xd4$\xef\xcc\x12}Scs=c3\x05\ro\x8f\x10_\x1f\x1d\x85\x9c\xcc\xecT\x05\xf7\xd4\xe4\xec|M\x05\xe7\x0c`\x89\x96\xaaol\xa8g\xa0ghfj\xa0g\x06L\x0b\x89i\x89E\x99P]\x00\x00\x00\x00\xff\xff\x80\x03\x00\x01\x00\x00\x00)\x00\x00\x00\x03\x00\x00\x00\x00`\x00\xa2\xcc\x87\x00\x01\x94\x98\x93Y\x90X\xa9\x97\x9c\x9fkebb\x0c\x10@\x83\xd3\x87\x00\x00\x00\x00\xff\xff'
    (2)2014-01-06 14:44:55,071 proxy           DEBUG: [49036176] >-- <SETTINGS SETTINGS_MAX_CONCURRENT_STREAMS=1000 SETTINGS_INITIAL_WINDOW_SIZE=10485760  [20]>
    (3)2014-01-06 14:44:55,073 proxy           DEBUG: [49036176] >-- <SYN_STREAM #1->#0 [191]:host: alipay.com  :method: CONNECT    :version: HTTP/1.1  :path: alipay.com:443   user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36    >
    (4)2014-01-06 14:44:55,074 proxy           DEBUG: [49036176] error Error -3 while decompressing data: incorrect header check
    (5)2014-01-06 14:44:55,074 proxy           DEBUG: [49036176] zlib.e b'\x80\x03\x00\x01\x00\x00\x00)\x00\x00\x00\x03\x00\x00\x00\x00`\x00\xa2\xcc\x87\x00\x01\x94\x98\x93Y\x90X\xa9\x97\x9c\x9fkebb\x0c\x10@\x83\xd3\x87\x00\x00\x00\x00\xff\xff'
    (6)2014-01-06 14:45:25,070 proxy           DEBUG: [49036176] on_read b'\x80\x03\x00\x03\x00\x00\x00\x08\x00\x00\x00\x01\x00\x00\x00\x05\x80\x03\x00\x01\x00\x00\x00)\x00\x00\x00\x05\x00\x00\x00\x00`\x00\xa2\xcc\x87\x00\x01\x94\x98\x93Y\x90X\xa9\x97\x9c\x9fkebb\x0c\x10@\x83\xd3\x87\x00\x00\x00\x00\xff\xff\x80\x03\x00\x03\x00\x00\x00\x08\x00\x00\x00\x03\x00\x00\x00\x05'
    (7)2014-01-06 14:45:25,072 proxy           DEBUG: [49036176] >-- <RST_STREAM #1 [8]CANCEL>
    

    让我解释一下:

    (1)代理收到套接字的原始字节,其中包含3个spdy帧

    (2)从(1)

    的字节解析SETTINGS帧
    b'\x80\x03\x00\x04\x00\x00\x00\x14\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x03\xe8\x00\x00\x00\x07\x00\xa0\x00\x00
    

    (3)还解析了SYN_STREAM帧

    b'\x80\x03\x00\x01\x00\x00\x00\xbf\x00\x00\x00\x01\x00\x00\x00\x00\x00\x008\xea\xe3\xc6\xa7\xc2\x02e%\x10\xb6\x82\x16\x08\\\xc0\xd4U\x90X\xa9\x97\x0c.&\xd8\xad\xe0\x89\x99\xdd\xd9\xdf\xcf\xcf\xd59\x04\xac\xb8 \x11\\l\xf1\x01\x04PbNfAb\xa5^r~\xae\x95\x89\x891@\x00\x81\x12\xb3\x15\xf6\x84\x8d\x9a\xa1r|\xf3\xab2sr\x12\xf5M\xf5\x0c\x144\xc23\xf3R\xf2\xcb\x8b\x15\xfcB\x14\xcc\xf4\x0c\xad\x15\xc2\xfd\xc3\xcdL4\x811\x06\x8c\xdf\xf0\xd4$\xef\xcc\x12}Scs=c3\x05\ro\x8f\x10_\x1f\x1d\x85\x9c\xcc\xecT\x05\xf7\xd4\xe4\xec|M\x05\xe7\x0c`\x89\x96\xaaol\xa8g\xa0ghfj\xa0g\x06L\x0b\x89i\x89E\x99P]\x00\x00\x00\x00\xff\xff'
    

    (4)解析继续时,遇到另一个SYN_STREAM

    b'\x80\x03\x00\x01\x00\x00\x00)\x00\x00\x00\x03\x00\x00\x00\x00`\x00\xa2\xcc\x87\x00\x01\x94\x98\x93Y\x90X\xa9\x97\x9c\x9fkebb\x0c\x10@\x83\xd3\x87\x00\x00\x00\x00\xff\xff'
    

    但是某种程度上名称/值块部分无法解压缩

    6-8个字节表示剩余数据的长度(长度:'\ x00 \ x00)'= 41),尾部是'\ x00 \ x00 \ xff \ xff',所以我应该拆分框架正确。

    在'length bytes'之后,在压缩的名称/值块之前还有10个其他字节。

    (5)捕获错误,列出了故障帧的字节,实际压缩名称/值块的字节是:

    b'\xa2\xcc\x87\x00\x01\x94\x98\x93Y\x90X\xa9\x97\x9c\x9fkebb\x0c\x10@\x83\xd3\x87\x00\x00\x00\x00\xff\xff'
    

    (6/7)我暂时没有回答chrome,所以它发送了一个RST_STREAM帧来取消之前的SYN_STREAM请求(3)(这没关系)

    解压缩功能有什么问题?

    或有人知道如何解压第二个SYN_STREAM的NV块吗?

    谢谢!

    编辑

    我添加了一个完整的日志示例。

    感谢@Mark,我看到.flush()没有被调用,但主要错误是'错误的标题')

1 个答案:

答案 0 :(得分:1)

你需要冲洗。 E.g:

temp = decompressor.decompress(buf)
return temp + decompressor.flush()

即便如此,您提供的数据也不是有效的zlib流。它可能是上一个流的延续吗?