gzip エンコーディングでチャンク化されたデータをどのように管理しますか? 次の方法でデータを送信するサーバーがあります。
HTTP/1.1 200 OK\r\n
...
Transfer-Encoding: chunked\r\n
Content-Encoding: gzip\r\n
\r\n
1f50\r\n\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03\xec}\xebr\xdb\xb8\xd2\xe0\xef\xb8\xea\xbc\x03\xa2\xcc\x17\xd9\xc7\xba\xfa\x1e\xc9r*\x93\xcbL\xf6\xcc\x9c\xcc7\xf1\x9c\xf9\xb6r\xb2.H ... L\x9aFs\xe7d\xe3\xff\x01\x00\x00\xff\xff\x03\x00H\x9c\xf6\xe93\x00\x01\x00\r\n0\r\n\r\n
これにはいくつかの異なるアプローチがありましたが、ここで忘れていることがあります。
data = b''
depleted = False
while not depleted:
depleted = True
for fd, event in poller.poll(2.0):
depleted = False
if event == select.EPOLLIN:
tmp = sock.recv(8192)
data += zlib.decompress(tmp, 15 + 32)
与えます(また、\r\n\r\n
obvの後にデータのみをデコードしようとしました):
zlib.error: Error -3 while decompressing data: incorrect header check
したがって、データが完全な形式で受信されたら、データを解凍する必要があると考えました..
...
if event == select.EPOLLIN:
data += sock.recv(8192)
data = zlib.decompress(data.split(b'\r\n\r\n',1)[1], 15 + 32)
同じエラー。data[:-7]
また、データの最後にあるチャンクIDとdata[2:-7]
、その他のさまざまな組み合わせのために解凍を試みましたが、同じエラーが発生しました。
gzip
また、次の方法でモジュールを試しました。
with gzip.GzipFile(fileobj=Bytes(data), 'rb') as fh:
fh.read()
しかし、それは「gzipされたファイルではありません」となります。
サーバーによって受信されたデータ (ヘッダー + データ) をファイルに記録し、ポート 80 でサーバー ソケットを作成してデータを (再びそのまま) ブラウザに提供した後でも、完全にレンダリングされるため、データは無傷。私はこのデータを取得し、ヘッダーを取り除き (他には何もありません)、ファイルで gzip を試しました。
@mark-adler のおかげで、チャンク化されたデータをアンチャンクする次のコードを作成しました。
unchunked = b''
pos = 0
while pos <= len(data):
chunkLen = int(binascii.hexlify(data[pos:pos+2]), 16)
unchunked += data[pos+2:pos+2+chunkLen]
pos += 2+len('\r\n')+chunkLen
with gzip.GzipFile(fileobj=BytesIO(data[:-7])) as fh:
data = fh.read()
これによりOSError: CRC check failed 0x70a18ee9 != 0x5666e236
、一歩近づいたものが生成されます。つまり、次の 4 つの部分に従ってデータをクリップします。
<chunk length o' X bytes>
\r\n
<chunk>
\r\n
私はおそらくそこに着いていますが、十分に近づいていません。
脚注: はい、ソケットは最適とはほど遠いですが、ソケットからすべてのデータを取得していないと思ったため、このように見えますdepleted
。