Kawa.netxp Content-Encoding: gzipのテスト

HTTP/1.1 では、コンテンツの圧縮転送ができるそうです。

最近はブロードバンドが普及しているため 多少のファイル容量は気にせず HTTP 転送されるようになってきていますが、 XML など無圧縮のテキスト形式で大量のデータを転送する場合には、 やはり今後もコンテンツの圧縮転送が必要になりそうです。

クライアント⇒サーバのリクエストヘッダでは Accept-Encoding: でブラウザ側が利用可能な圧縮形式を提示できます。
対してサーバ⇒クライアントのレスポンスヘッダでは Content-Encoding: でデータ本文の圧縮形式を通知できるようです。

自動判定〜動作確認サンプルプログラム

ブラウザが gzip 圧縮が利用可能かを自動判定して、 HTML 本文を圧縮転送する CGI サンプルプログラムを作成しました。

サンプルプログラムを実行する DEMO

『Using gzip: YES』と表示されれば、圧縮転送されています。
『Using gzip: NO』と表示されれば、通常通り無圧縮で転送されます。
それ以外の画面が出た場合は、ブラウザ側のエラーか、 またはサーバの不調ですね。

サンプルプログラムのソースは以下の通りです。

#!/usr/bin/perl
# gzip-test.cgi ---- sample for "Content-Encoding: gzip"
# Copyright 2005 Yusuke Kawasaki
# http://www.kawa.net/works/perl/contenc/gzip.html

use strict; 
use Compress::Zlib;     # gzip 圧縮モジュール

# Accept-Encoding: のカンマ区切りを展開する
my $usegzip;
foreach my $enc ( split( /\s*,\s*/, $ENV{HTTP_ACCEPT_ENCODING} )) {
    $enc =~ s/;.*$//s;      # ; qs= 等は無視する
    $usegzip = $enc if ( $enc =~ /^(x-)?gzip$/ );
}

# 圧縮可能な場合は   Content-Encoding: gzip
# 圧縮不可能な場合は Content-Encoding: identity ⇒書かない
print "Content-Encoding: $usegzip\n" if $usegzip;

# HTTPヘッダを出力する
print "Content-Type: text/html\n\n";

# 本文を作成する(配列に突っ込んでいく)
my $out = [];
push( @$out, "Using gzip: ".($usegzip ? "YES" : "NO")."<BR>\n" );
push( @$out, "<br>\n" );
foreach my $key (qw( HTTP_ACCEPT_ENCODING HTTP_USER_AGENT )) {
    my $val = $ENV{$key};
    $val =~ s/&/&amp;/g;
    $val =~ s/</&lt;/g;
    $val =~ s/>/&gt;/g;
    push( @$out, "$key = $val<br>\n" );
}

# 本文を1変数にまとめる
my $body = join( "", @$out );

# 圧縮可能な場合は本文を圧縮する
$body = Compress::Zlib::memGzip( $body ) if $usegzip;

# そのまま出力する
print $body;

なお、HTTP/1.1 として利用できるエンコーディングは、 gzip、compress、deflate、identity のみ のようです。 (拡張はない)
なお、identity(デフォルト=無圧縮)の場合は、 互換のため Content-Encoding: ヘッダも出力しません。

gzip 転送対応のブラウザ

手元で確認しているところ、以下のようになっています。

携帯電話が対応していると、パケ代節約になって良さそうですけどね。

Internet Explorer 6.0はgzip転送に対応しているけど・・・

Internet Explorer 6.0はgzip転送に対応していますが、 オプションで利用禁止にできるようです。
デモにInternet Explorer 6.0アクセスして『Using gzip: NO』と表示される場合は、

インターネットオプション⇒詳細設定⇒HTTP 1.1 設定⇒HTTP 1.1 を使用する
をONにしてから、Internet Explorerを再起動してください。
(ブラウザの全てのウインドウを閉じてから、ブラウザを起動し直す)

Content Negotiation でサーバ側で自動的に判別

ディレクトリ中に hoge.xml と hoge.xml.gz のファイルがあるとき、 Apache の mod_negotiation モジュールにより、 コンテントネゴシエーションの機能が働いて 『Accept-Encoding: gzip』なブラウザからのアクセスでは自動的に hoge.xml.gz を返し、 そうでない場合は通常通り hoge.xml を返す仕組みがあるようです。

この機能を使えば、静的 XML ファイルの圧縮転送は容易に実現できます。
しかし、Apache 2.0 系では特に設定せずにこの機能が動きましたが、 Apache 1.3 系でこの機能を利用する手順は分かりませんでした。残念。 どうやって設定するのでしょう?

その他のページへのリンク

コメントはこちらへ by AjaxCom

このページへのトラックバック by AjaxTB

トラックバックURL:http://www.kawa.net/service/tb/ajaxtb.cgi/works/perl/contenc/gzip.html

Kawa.netxp © Copyright 2002-2005 Yusuke Kawasaki