HTTP_Request 1.4.1はdeflateをデコードしないようだ

レスポンスヘッダに"Content-Encoding: deflate"とある場合、HTTP_Requestはデコードしない模様。
Request #11246 Problem with deflate encoding

HTTP_Requestは、リクエストヘッダのContent-Encodingを探し、その値がgzipだった場合に自動的にデコードしてくれます。ところが、"Content-Encoding: deflate"の場合にはデコードしてくれません。ソースを読む限り、gzip圧縮の判定を「Content-Encodingの値がgzipである場合」としており、それ以外についてはどこにも記述されていません。deflateは無視しているようです。

gzipのデコードは_decodeGzipメソッドで行われます。PHPにはgzinflate関数が用意されており、_decodeGzipメソッドでも伸長処理にはこれを使っています。ただし、RFC1952に従ったパース処理などを行ってから、gzinflate関数を実行します。このため、deflateのデコードを_decodeGzipメソッドで行うのは駄目っぽいです。

ひとまず、deflateの場合はgzinflate関数で伸長するようにしてその場をしのいでおきます。


Zend_Http_Response::decodeDeflateでは、gzuncompress関数を使っているようです。一方で、Zend_Http_Response::decodeGzipではgzinflate関数を使ってるのはなぜでしょうか。やはり、deflate圧縮とgzip圧縮について深追いしないと駄目でしょうか。

PHPのドキュメントに、「HTTPサーバの言うdeflateとPHPの言うdeflateは違う」というようなことが書いてありました。

Take care that that "PHP deflate" != "HTTP deflate".

The deflate encoding used in HTTP is actually zlib encoded.

This is what PHP functions return:
gzencode() == gzip
gzcompress() == zlib (aka. HTTP deflate)
gzdeflate() == *raw* deflate encoding
PHP: gzdeflate - Manual

RFCを見てみると、なんだかんだでzlibとの事。つまり、PHPのgzuncompress関数を使うのが正しい模様。

The "zlib" format defined in RFC 1950 [31] in combination with the "deflate" compression mechanism described in RFC 1951 [29].
RFC 1951 [29] に記述されている "deflate" 圧縮メカニズムと結合した、RFC 1950 [31] にて定義されている "zlib" フォーマット。
ハイパーテキスト転送プロトコル -- HTTP/1.1

(gzinflate関数で解決できた)URLについてgzuncompress関数を使うようにしたところ、gzuncompress関数がfalseを返しました。とりあえず、gzuncompress関数→gzinflate関数という体制でやっておくことにしてみます。

また別のURLについて試したところ、gzuncompress関数で正しく処理され、gzinflate関数でfalseとなりました。サーバによってはdeflateのデータフォーマット(?)が違うようですね。

プロフィール

このブログ記事について

このページは、koshigoeが2007年8月14日 17:17に書いたブログ記事です。

ひとつ前のブログ記事は「ドタキャンすべきだろうか」です。

次のブログ記事は「猛省:PHPのセッション有効期限とGC」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。