画像ファイルのアップロード 【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); |
これで,ファイルを出力。