HTTPプロトコルを利用したSTDINによるファイル転送の実験
「GIF/JPEG転送表示」

browse.cgi

HTTP は何となく受信専用のプロトコルと思いがち.ですが,こんな風にすればバイナリファイルの転送だってできるのです.Geocities なんかのファイルのアップロードはこの方法を使ってますね.

■ CGI を起動する HTML のタグに

<FORM ENCTYPE="multipart/form-data"
METHOD=POST ACTION="起動CGI名">
を記述する.入力フォームは, <INPUT TYPE="file" ....> のタグを使います.

■ そのデータを受信する CGI(Perl) はこんな風にします.

binmode (STDIN);
read (STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

binmode... は 転送モードを Binary にする.
read...は STDIN からの受信データを $buffer に入れる.

■ つづいて,受信されるデータには不要なヘッダーが付加されているので,これを除去して必要な部分を取り出します.(本当はここにローカルのファイル名とかが含まれているのですが,今回は使わないので)
@data = split (/Content-Type/, $buffer);
$data[0] = 'Content-Type';
if ($data[1] =~ /image\/gif/i || $data[1] =~ /image\/jpeg/i) {
  ($fileend, $delete) = split (/\x0d\x0a\x2d\x2d/, $data[$#data]);
  $buffer = '';
  for ($i = 0; $i < $#data; $i++) {
    $buffer = "$buffer$data[$i]";
  }
  $buffer = "$buffer$fileend";
  binmode (STDOUT);
  print "$buffer";
  exit (0);
}
else {
  print "Content-Type: text/html\n\n";
  print '<HTML><BODY>This file type is not visible.</BODY></HTML>';
  exit (1);
}

1行目で Content-Type でデータを区切ります.$data[0]にヘッダーの一部,$data[1]には gif ファイルならば,image/gif\n\nのあとにバイナリの画像データ,不要なファイルエンド部分が含まれます.$data[0]に必要なHTTPヘッダー"Content-Type"を取り付けます.$data[1]の最初の部分にgifまたはjpegが含まれていれば画像として表示する部分に処理が移されます(ifクローズの内部).それ以外のファイルはエラー表示となります(elseクローズの部分).
ifクローズの内部処理ですが,$data[0]と$data[1..]を再び$bufferとして結合し,今度はブラウザにバイナリを転送するためにbimode(STDOUT)で送信をバイナリに設定し,画像を表示させます.

■ この方法を利用すれば,バイナリファイルをサーバーへ転送することも可能です.ただし,注意しなければならないことは転送するファイルサイズが大きいと,それだけサーバーに負担を増大することになります.CGIの実行時間を限定しているサーバーなどではできないかもしれません.従って一応,ここで公開しているサンプルCGIはサイズをチェックして10KBを越えるものは拒否するようになっています.

あなたのパソコンにある,GIF あるいは JPEG 画像をブラウザに表示します.
ただし,あまりでっかいのは拒否します.





戻 る