画像ファイルのアップロード 【1】    w-w9-warewan.cgi の動作解析] 

                                          

[その1] その動作概要 
 

 FTP等を使うことなしに,ブラウザ上から,画像ファイルをサーバー側に
送る。これにより,画像付きの掲示板等が可能となる。


[その2] 簡単な画像の読み込み・書き込み 

binmodetest.cgi   

#!/usr/local/bin/perl

$| = 1;
$imagefile = "binmodetest.jpg";

open IMG,"$imagefile";

binmode IMG;
binmode STDOUT;

$MAX_SIZE = (-s $imagefile);

print "Contend-type: image/jpg\n\n";

while(read(IMG,$imagedate,$MAX_SIZE)){
  print $imagedate;
}
close IMG;

exit;
 
 

# 出力バッファ・強制フラッシュ



# イメージデータの読み込み


# 変数モード
# 標準出力モード

# イメージのサイズ

# 出力タイプ

#イメージの出力
 

binmodeが必要な理由

binmode IMG;
binmode STDOUT;

 例の改行コードの関係で必要らしい。



[その3] 転送ファイルの選択 

w-w9-warewan.cgi  より   


転送ファイル


<FORM method="post" enctype="multipart/form-data"
action="http://127.0.0.1/~JU8Y-HSTN/cgi-bin/warewan/upload.cgi">
<B><FONT size="+1">転送ファイル</FONT></B>
<INPUT
type="file" name="/img">
<INPUT type="submit" value="送信">
</FORM>


enctype="multipart/form-data"

 フォームデータを各項目ごとに個別ファイルとして転送する。

type="file"

 任意のファイルを「参照..」で選択可能となる。



[その4] JPGファイルの構造 

     

1.  RED_BLUE.jpg


2.  RED_BLUE.jpg のファイル構造

00000000 : FF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 00 48 : ......JFIF.....H
00000010 : 00 48 00 00 FF DB 00 43 00 05 03 04 04 04 03 05 : .H.....C........
00000020 : 04 04 04 05 05 05 06 07 0C 08 07 07 07 07 0F 0B : ................
00000030 : 0B 09 0C 11 0F 12 12 11 0F 11 11 13 16 1C 17 13 : ................
00000040 : 14 1A 15 11 11 18 21 18 1A 1D 1D 1F 1F 1F 13 17 : ......!.........
00000050 : 22 24 22 1E 24 1C 1E 1F 1E FF DB 00 43 01 05 05 : "$".$.......C...
00000060 : 05 07 06 07 0E 08 08 0E 1E 14 11 14 1E 1E 1E 1E : ................
00000070 : 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E : ................
00000080 : 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E : ................
00000090 : 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E FF C0 : ................
000000A0 : 00 11 08 00 32 00 32 03 01 22 00 02 11 01 03 11 : ....2.2.."......
000000B0 : 01 FF C4 00 15 00 01 01 00 00 00 00 00 00 00 00 : ................
000000C0 : 00 00 00 00 00 00 00 07 FF C4 00 14 10 01 00 00 : ................
000000D0 : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF C4 : ................
000000E0 : 00 16 01 01 01 01 00 00 00 00 00 00 00 00 00 00 : ................
000000F0 : 00 00 00 00 07 08 FF C4 00 18 11 01 00 03 01 00 : ................
00000100 : 00 00 00 00 00 00 00 00 00 00 00 00 17 64 A3 E3 : .............d.
00000110 : FF DA 00 0C 03 01 00 02 11 03 11 00 3F 00 96 00 : ............?...
00000120 : 9D 36 58 00 00 00 00 02 68 34 44 09 7F 2E 88 4C : .6X.....h4D..L
00000130 : D7 4B 4E 6A 58 9A 04 09 7F 2E 84 D7 4B 4E 6A 58 : .KNjX....ラKNjX
00000140 : 9A 04 09 7F 2E 84 D7 4B 4E 6A 58 9A 04 09 7F 2E : ....ラKNjX....
00000150 : 84 D7 4B 4E 60 0D 10 84 00 00 00 00 00 00 00 00 : ラKN`...........
00000160 : 00 00 03 FF D9                   : .....



3.  RED_BLUE.jpg のPOSTデータ構造

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

 下記のように,

   [ヘッダー] + 画像データ + [フッター]

となっている。 ただし,これは 「Windows」上での結果。

00000000 : 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D : ----------------
00000010 : 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 37 63 66 : -------------7cf
00000020 : 32 64 30 31 61 62 39 63 0D 0A 43 6F 6E 74 65 6E : 2d01ab9c..Conten
00000030 : 74 2D 44 69 73 70 6F 73 69 74 69 6F 6E 3A 20 66 : t-Disposition: f
00000040 : 6F 72 6D 2D 64 61 74 61 3B 20 6E 61 6D 65 3D 22 : orm-data; name="
00000050 : 2F 69 6D 67 22 3B 20 66 69 6C 65 6E 61 6D 65 3D : /img"; filename=
00000060 : 22 43 3A 5C 54 45 53 54 5C 52 45 44 5F 42 4C 55 : "C:\TEST\RED_BLU
00000070 : 45 2E 6A 70 67 22 0D 0A 43 6F 6E 74 65 6E 74 2D : E.jpg"..Content-
00000080 : 54 79 70 65 3A 20 69 6D 61 67 65 2F 70 6A 70 65 : Type: image/pjpe
00000090 : 67 0D 0A 0D 0A FF D8 FF E0 00 10 4A 46 49 46 00 : g..........JFIF.
000000A0 : 01 01 01 00 48 00 48 00 00 FF DB 00 43 00 05 03 : ....H.H.....C...
000000B0 : 04 04 04 03 05 04 04 04 05 05 05 06 07 0C 08 07 : ................
000000C0 : 07 07 07 0F 0B 0B 09 0C 11 0F 12 12 11 0F 11 11 : ................
000000D0 : 13 16 1C 17 13 14 1A 15 11 11 18 21 18 1A 1D 1D : ...........!....
000000E0 : 1F 1F 1F 13 17 22 24 22 1E 24 1C 1E 1F 1E FF DB : ....."$".$......
000000F0 : 00 43 01 05 05 05 07 06 07 0E 08 08 0E 1E 14 11 : .C..............
00000100 : 14 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E : ................
00000110 : 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E : ................
00000120 : 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E : ................
00000130 : 1E 1E 1E FF C0 00 11 08 00 32 00 32 03 01 22 00 : .........2.2..".
00000140 : 02 11 01 03 11 01 FF C4 00 15 00 01 01 00 00 00 : ................
00000150 : 00 00 00 00 00 00 00 00 00 00 00 00 07 FF C4 00 : ................
00000160 : 14 10 01 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................
00000170 : 00 00 00 FF C4 00 16 01 01 01 01 00 00 00 00 00 : ................
00000180 : 00 00 00 00 00 00 00 00 00 07 08 FF C4 00 18 11 : ................
00000190 : 01 00 03 01 00 00 00 00 00 00 00 00 00 00 00 00 : ................
000001A0 : 00 17 64 A3 E3 FF DA 00 0C 03 01 00 02 11 03 11 : ..d.............
000001B0 : 00 3F 00 96 00 9D 36 58 00 00 00 00 02 68 34 44 : .?....6X.....h4D
000001C0 : 09 7F 2E 88 4C D7 4B 4E 6A 58 9A 04 09 7F 2E 84 : ..L.KNjX....ラ
000001D0 : D7 4B 4E 6A 58 9A 04 09 7F 2E 84 D7 4B 4E 6A 58 : .KNjX....ラKNjX
000001E0 : 9A 04 09 7F 2E 84 D7 4B 4E 60 0D 10 84 00 00 00 : ....ラKN`......
000001F0 : 00 00 00 00 00 00 00 03 FF D9 0D 0A 2D 2D 2D 2D : ............----
00000200 : 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D 2D : ----------------
00000210 : 2D 2D 2D 2D 2D 2D 2D 2D 2D 37 63 66 32 64 30 31 : ---------7cf2d01
00000220 : 61 62 39 63 2D 2D 0D 0A              : ab9c--..




[その5] 画像データの取りだし 


$pos = index($read_data, "\r\n\r\n") + 4;
$size = $ENV{'CONTENT_LENGTH'} - $pos;
$date = substr($read_data, $pos, $size);

 「 0D 0A 0D 0A 」  が 「 \r\n\r\n 」 で画像データのスタート位置を検出

 substr で 画像データを抜き出す。

 フッターは? 

open(OUT, ">$number.jpg");
binmode(OUT);
print OUT $date;
close(OUT);

これで,ファイルを出力。