HTTPプロトコルを利用したSTDINによるファイル転送の実験
「バイナリファイルの転送」

bintrans.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 (/\x0d\x0a\x0d\x0a/, $buffer);
($fileend, $delete) = split (/\x0d\x0a\x2d\x2d/, $data[$#data]);
$buffer = '';
for ($i = 1; $i < $#data; $i++) {
$buffer = "$buffer$data[$i]";
}
$buffer = "$buffer$fileend";
open (OUT, ">bintrans.bin");
binmode (OUT);
print OUT "$buffer";
close (OUT);
print "Content-Type: text/html\n\n";
print "<HTML><BODY>Upload Finished.</BODY></HTML>";
exit(0);

HTTPプロトコルで転送されるファイルのヘッダー・フッターの区切りは,STDINによって転送される際にそれぞれ"0x0d 0x0a 0x0d 0x0a"と"0x0d 0x0a 0x2d 0x2d"となります.この間に存在するバイナリが,ローカルから転送された部分となります.すなわちサーバー側でローカルから送られた必要なデータを取り出すには,その部分だけを利用できればいいわけです.ここでは,サーバーに送られたデータは"bintrans.bin"として保存されるようになっています.

■ この方法を利用すれば,バイナリファイルをサーバーへ転送することも可能です.ただし,注意しなければならないことは転送するファイルサイズが大きいと,それだけサーバーに負担を増大することになります.CGIの実行時間を限定しているサーバーなどではできないかもしれません.ここのHPがつぶれてしまうおそれがありますので,サンプル実行はありません.下のリンク部分から,サンプルがダウンロード出来ます.

BINTRANS.CGIサンプルのダウンロード

戻 る