[Edit][Create New]
[ IndexPage / ネットとプログラミング / web296 / No38.txt ]

No38.txt

さて、今回は前回に引き続き、gzip圧縮を使ったコンテンツの送信について解
説します。本来gzip圧縮によるコンテンツ送信はWebサーバー側で面倒をみる
ものなのですが、今回は「2ちゃんねる閉鎖騒動」の時と同じくWebサーバーの
設定をいじることができないという前提で、CGI側のみでgzip対応する方法を
解説します。

なお、10月24日発売の技術評論社「WEB+DB PRESS Vol.5」にも、2ちゃんねる
閉鎖騒動に関する拙文が6ページほど掲載される予定ですので、もし興味があ
りましたら読んでみてください。

まず今回は多少CGIとPerlに関する知識が必要になりますが、ご容赦ください。

CGIスクリプトは、Webサーバーと同じく呼び出された時に、ブラウザから様々
な情報を受け取ります。これらの情報は、環境変数と呼ばれる変数に保存され、
Perlの場合は、「%ENV」という特殊変数(ハッシュ)に保存されるようになりま
す。

さて、ブラウザは、自分自身がgzip圧縮に対応している事をWebサーバーに伝
えるために、

Accept-Encoding: gzip

のような行を付加するのでしたね。この「gzip」の部分は、CGIでは次のよう
にして取り出すことができます。

$ENV{HTTP_ACCEPT_ENCODING}

この$ENV{}の中でAccept-Encodingを指定している訳です。指定に使う文字列
は、ヘッダの名前を全て大文字にし、その上でハイフン(-)をアンダースコア
(_)に変換し、さらに先頭に「HTTP_」が付加されたものが使われます。
Accept-Encodingの場合は、HTTP_ACCEPT_ENCODINGとなります。実際に評価する際は、


if($ENV{HTTP_ACCEPT_ENCODING} =~ /gzip/){
# gzip圧縮対応
}else{
# gzip圧縮非対応
}

という処理の流れになります(厳密にはこれだとまずい場合が稀にあるのです
が、文字数の都合で割愛します)。

さて、非対応ならそのままコンテンツを流してやればよいのですが、そうでな
い場合はどうすれば良いのでしょうか? 前回も解説しましたが、ブラウザに返
すヘッダに、

Content-Encoding: gzip

という行を付加し、内容をgzipで圧縮して送信してやれば良いのでしたね。

それでは以下に、ブラウザによってテキスト"longlongtext.txt"の出力を変え
る簡易CGIスクリプトを示して今回は終わりとします。好評なようなら、次回
からも引き続き2ちゃんねる転送量削減問題について解説するつもりです。

#!/usr/bin/perl

print "Content-Type: text/plain\n"; # テキストファイルであることを宣言

if($ENV{HTTP_ACCEPT_ENCODING} =~ /gzip/){
print "Content-Encoding: gzip\n"; # gzipであることを宣言
print "\n"; # ヘッダの終わり
# ↓ -cfは、gzip圧縮に標準入出力を使うためのオプション 
system("cat longlongtext.txt | gzip -cf");
}else{
print "\n"; # ヘッダの終わり
system("cat longlongtext.txt"); # 単純にテキストファイルを表示
}