TOP > スクリプト制作メモ > gzip圧縮転送について

≫gzip圧縮転送とは

CGI でデータを転送する際に、圧縮をかけてデータ転送を高速化します。

まずサーバが生成したデータを圧縮します。それをブラウザに送信し、ブラウザが受信したデータを解凍・表示するという感じです。転送経路で圧縮されたデータがやり取りされるので、通常よりも転送資源を消費しません。また、サーバの転送にかかるCPU負荷も抑えることが出来ます。

この機能は導入が簡単な割に HTTP1.1 の中のいたって普通の仕様なのでカナリ幅広く活用することができます。大量のテキストデータをやり取りするような掲示板プログラムにはもってこいです。また、大量でなくても転送データの節約に役立つ機能であることは間違いありません。

技術的には、gzip は RFC 1952 に記述されているファイル圧縮プログラム "gzip" (GNU zip) によって作られますが、利用上特に意識する必要はありません(運動力学を知らなくても自転車には乗れます)。

ただ、この機能はブラウザが対応していないと意味がありません。対応していないというのは、サーバがせっかく圧縮して送ってきたデータを、ブラウザが解凍・表示できないということです。

しかし、普及率96%以上(?!)のIEやネットスケープはバージョン4以降対応済みで、それらをブラウジングエンジンとして利用しているタブブラウザなども対応しています。つまり、ほとんどのブラウザでは対応しているということです。

ただし、数は少ないながら対応していないブラウザでは見られないといった事態は避けたいので、プログラム的に対処することにします。

では、以下に gzip圧縮転送 に対応するためのコードを記述します。

≫gzip圧縮転送 実装コード

普段 Content-type: を吐いている部分を以下のコードで置き換えます。


$gzip = '/bin/gzip/';

if($ENV{'HTTP_ACCEPT_ENCODING'} =~ /gzip/ && $gzip ne ''){ 

  print "Content-type: text/html;charset=Shift_JIS\n";

  if($ENV{'HTTP_ACCEPT_ENCODING'} =~ /x-gzip/){

    print "Content-encoding: x-gzip\n\n";

  }else{

    print "Content-encoding: gzip\n\n";

  }

  open(STDOUT,"| $gzip -1 -c");

}else{

  print "Content-type: text/html;charset=Shift_JIS\n\n";

}


$gzip = '/bin/gzip/';
gzip のパスを設定します。telnet で入って which で探すか、サーバ管理者に問い合わせましょう。

if($ENV{'HTTP_ACCEPT_ENCODING'} =~ /gzip/ && $gzip ne ''){
環境変数の HTTP_ACCEPT_ENCODING に gzip があるか、$gzip が未設定ではないか判定しています。

print "Content-type: text/html;charset=Shift_JIS\n";
まずは、Content-type の出力です。文字コードは環境に合わせて変更する必要があります。

if($ENV{'HTTP_ACCEPT_ENCODING'} = ~ /x-gzip/){
環境変数 HTTP_ACCEPT_ENCODING が x-gzip 対応か

print "Content-encoding: x-gzip\n\n";
x-gzip 対応なので、エンコード方式を x-gzip だと指定します。

print "Content-encoding: gzip\n\n";
普通に gzip 対応なので、エンコード方式を gzip だと指定します。x-gzip と gzip はこれといった違いはないようですが…。

open(STDOUT,"| $gzip -1 -c");
出力先を gzip にパイプでつなぎます。STDOUT は標準出力。-1 -c はオプションです。

print "Content-type: text/html;charset=Shift_JIS\n\n";
gzip に対応していない場合は、Content-type を吐いて終了です。




汎用的なルーチンとして、以下のものを挙げておきますのでご利用願います。


$gzip = '/bin/gzip/';
print "Content-type: text/html;charset=Shift_JIS\n";
if($ENV{'HTTP_ACCEPT_ENCODING'} =~ /gzip/ && $gzip ne ''){  
  if($ENV{'HTTP_ACCEPT_ENCODING'} =~ /x-gzip/){
    print "Content-encoding: x-gzip\n\n";
  }else{
    print "Content-encoding: gzip\n\n";
  }
  open(STDOUT,"| $gzip -1 -c");
}else{
  print "\n";
}



TOP > スクリプト制作メモ > gzip圧縮転送について
(C) bayashi.net