web-dev-qa-db-ja.com

チャンクエンコーディング応答のgzip圧縮?

私のウェブサーバーにチャンクエンコーディングであるhttpレスポンスを正しくgzipさせようとしています。

非gzip応答についての私の理解は、次のようになることです。

<the response headers>

そして、各チャンクについて、

<chunk length in hex>\r\n<chunk>\r\n

そして最後に、長さゼロのチャンク:

0\r\n\r\n

私はgzip圧縮を機能させようとしましたが、実際に何が返されるべきかを理解するのにいくつかの助けが必要でした。このドキュメントでは、各チャンクをgzip圧縮するのではなく、応答全体をgzip圧縮する必要があることを示しています。

HTTP servers sometimes use compression (gzip) or deflate methods to optimize transmission.
Chunked transfer encoding can be used to delimit parts of the compressed object.
In this case the chunks are not individually compressed. Instead, the complete payload 
is compressed and the output of the compression process is chunk encoded.

私は全体をgzipしてチャンクしなくても応答を返そうとしましたが、うまくいきませんでした。 Content-Encodingヘッダーを「gzip」に設定してみました。チャンクのgzip圧縮をサポートするために、上記のスキームにどのような変更を加える必要があるかを誰かが説明できますか?ありがとう。

コンテンツをgzipし、チャンクエンコーディングを適用します。

「チャンク」はHTTP/1.1受信者が理解する必要がある唯一の転送コーディングであるため、永続的な接続でメッセージを区切るのに重要な役割を果たします。転送コーディングがリクエストのペイロードボディに適用されると、適用される最終的な転送コーディングは「チャンク」する必要があります。転送ペイロードが応答ペイロード本体に適用される場合は、適用される最終的な転送コーディングを「チャンク」するか、メッセージを接続を閉じることによって終了する必要があります。 「チャンクされた」転送コーディングが使用されます。これは、メッセージ本文を形成するために適用された最後の転送コーディングでなければなりません。「チャンクされた」転送コーディングは、メッセージ本文で複数回適用されてはなりません。

HTTPbis Part1、Section 6.2.1

23
Julian Reschke

他の答えが十分に明確ではなかった場合:

まず、本体をzlibでgzipします(これはストリームで行うことができるため、一度に全部をメモリに入れる必要はありません。これがチャンクのポイントです)。

次に、Content-Encoding:gzipおよびTransfer-Encoding:chunkedヘッダー(およびContent-Lengthなし)を使用して、その圧縮された本文をチャンク(おそらくgzipストリームによって提供されたもの、チャンクヘッダーを使用して、その長さを宣言するもの)で送信します。ヘッダ)。

圧縮にgzipやzcatなどのユーティリティを使用している場合、おそらく機能しません。 zlibである必要があります。チャンクを作成してから圧縮する場合、それは確実に機能しません。これを正しく実行していて機能しない場合は、パケットトレースを取得し、それに基づいて、表示されたエラーメッセージに基づいて質問することをお勧めします。

33
sosiouxme

おそらく、適切にgzipされた応答を実際に送信していません。

Zlibで_window bits_を_31_に設定してみてください。そしてdeflateInit2()を使用します。

1
unixman83