さて、今回は前回に引き続き、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"); # 単純にテキストファイルを表示
}