ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

超初心者向けCGI講座コミュのpdfファイルをアップする。

  • mixiチェック
  • このエントリーをはてなブックマークに追加
Rocomotion(http://www.rocomotion.jp/)さんのROCO ALBUM を改造しようとしています。
このアルバムCGIに別途pdfファイルをアップできるようにしたいと思っています。
しかし、どうもうまく出来ません。

まずは、このCGIにはpdファイルをアップする機能がないので、同じサイトの他のプログラムにpdfファイルをアップできるものが無いかを探し、ROCO UP BOARD SEASON (http://www.rocomotion.jp/cgi/roco_up_board_season.php)でアップできることがわかったので、ここから移植しようと考えました。

しかし、移植すると、アップは出来るのですが、ファイルが壊れてしまいます。
アップしたファイルは元ファイルとファイルサイズが違っているし、Adobe Readerで開こうとすると、「ファイルが壊れています。」といったメッセージが出ます。
移植したサブルーチンは以下の通りです。
#--------------------#
# PDFアップロード #
#--------------------#
sub UpFilepdf {
# 画像処理
$macbin=0;
foreach (@in) {
if ($_ =~ /(.*)Content-type:(.*)/i) { $tail=$2; }
if ($_ =~ /(.*)filename=(.*)/i) { $fname=$2; }
if ($_ =~ /application\/x-macbinary/i) { $macbin=1; }
}
$tail =~ s/\r//g;
$tail =~ s/\n//g;
# $fname =~ s/\"//g;
$fname =~ tr/\"\x0D\x0A//d;

# ファイル形式を認識
$flag=0;
if ($tail =~ /image\/gif/i && $gif) { $tail=".gif"; $flag=1; }
if ($tail =~ /image\/jpeg/i && $jpeg) { $tail=".jpg"; $flag=1; }
if ($tail =~ /image\/x-png/i && $png) { $tail=".png"; $flag=1; }
if ($tail =~ /text\/plain/i && $text) { $tail=".txt"; $flag=1; }
if ($tail =~ /lha/i && $lha) { $tail=".lzh"; $flag=1; }
if ($tail =~ /zip/i && $zip) { $tail=".zip"; $flag=1; }
if ($tail =~ /pdf/i && $pdf) { $tail=".pdf"; $flag=1; }
if ($tail =~ /audio\/.*mid/i && $midi) { $tail=".mid"; $flag=1; }
if ($tail =~ /msword/i && $word) { $tail=".doc"; $flag=1; }
if ($tail =~ /ms-excel/i && $excel) { $tail=".xls"; $flag=1; }
if ($tail =~ /ms-powerpoint/i && $ppt) { $tail=".ppt"; $flag=1; }
if ($tail =~ /audio\/.*realaudio/i && $ram) { $tail=".ram"; $flag=1; }
if ($tail =~ /application\/.*realmedia/i && $rm) { $tail=".rm"; $flag=1; }
if ($tail =~ /video\/.*mpeg/i && $mpeg) { $tail=".mpg"; $flag=1; }
if ($tail =~ /audio\/.*mpeg/i && $mp3) { $tail=".mp3"; $flag=1; }

if (!$flag) {
if ($fname =~ /\.gif$/i && $gif) { $tail=".gif"; $flag=1; }
if (($fname =~ /\.jpe?g$/i && $jpeg)) { $tail=".jpg"; $flag=1; }
if ($fname =~ /\.png$/i && $png) { $tail=".png"; $flag=1; }
if ($fname =~ /\.lzh$/i && $lha) { $tail=".lzh"; $flag=1; }
if ($fname =~ /\.txt$/i && $text) { $tail=".txt"; $flag=1; }
if ($fname =~ /\.zip$/i && $zip) { $tail=".zip"; $flag=1; }
if ($fname =~ /\.pdf$/i && $pdf) { $tail=".pdf"; $flag=1; }
if ($fname =~ /\.mid$/i && $midi) { $tail=".mid"; $flag=1; }
if ($fname =~ /\.doc$/i && $word) { $tail=".doc"; $flag=1; }
if ($fname =~ /\.xls$/i && $excel) { $tail=".xls"; $flag=1; }
if ($fname =~ /\.ppt$/i && $ppt) { $tail=".ppt"; $flag=1; }
if ($fname =~ /\.ram$/i && $ram) { $tail=".ram"; $flag=1; }
if ($fname =~ /\.rm$/i && $rm) { $tail=".rm"; $flag=1; }
if ($fname =~ /\.mpe?g$/i && $mpeg) { $tail=".mpg"; $flag=1; }
if ($fname =~ /\.mp3$/i && $mp3) { $tail=".mp3"; $flag=1; }
}
# アップロード失敗処理
if (!$flag && !$clip_error) { return; }
elsif (!$flag && $clip_error) {
&error("アップロードできないファイル形式です","lock");
}

$upfile = $in{'upfilepdf'};

# マックバイナリ対策
if ($macbin) {
$length = substr($upfile,83,4);
$length = unpack("%N",$length);
$upfile = substr($upfile,128,$length);
}

# 添付データを書き込み
$ImgFile = "$ImgDir$no-pdf$tail";
open(OUT,"> $ImgFile") || &error("画像のアップロードに失敗しました","lock");
binmode(OUT);
binmode(STDOUT);
print OUT $upfile;
close(OUT);
chmod (0666,$ImgFile);

# 画像サイズ取得
if ($tail eq ".jpg") { ($W, $H) = &JpegSize($ImgFile); }
elsif ($tail eq ".gif") { ($W, $H) = &GifSize($ImgFile); }
elsif ($tail eq ".png") { ($W, $H) = &PngSize($ImgFile); }

# 画像表示縮小
if ($W > $MaxW || $H > $MaxH) {
$W2 = $MaxW / $W;
$H2 = $MaxH / $H;
if ($W2 < $H2) { $key = $W2; }
else { $key = $H2; }
$W = int ($W * $key) || 1;
$H = int ($H * $key) || 1;
}
$tailpdf = $tail;
}
#--------------------#
アップ出来ないとかだったら自分のミスとすぐわかるのですが、これではどこが悪いかが判りません。
どこをチェックしたらよいでしょうか?

お願いします。

コメント(8)

ちょっとperlに疎くなってしまっているので、ソースからは問題点を見つけることが出来ません。

良くありそうなところでは、$in{'upfilepdf'}に格納する時点とか?
バイナリデータを文字コード変換しようとすると壊れたりすることが良くあります。
大丈夫かとは思いますが、アップロード側の form タグの記述も同時に掲載していただけると嬉しいかも。

あと、サーバのOSがWindowsかUNIX系かでファイルオープン時のモードが異なりますので、
実行されている環境も書いていただけると。

返答ありがとうございます。

格納するほうは以下の通りです。

<form action=\"$script\" method=\"POST\" enctype=\"multipart/form-data\">
<INPUT type="file" size="34" name="upfilepdf">

upFilepdfには何を渡しているんですかね。

呼び出し元が書いていないから、なおさらよくわかりません。

ちなみに

>アップしたファイルは元ファイルとファイルサイズが違っているし、
>Adobe Readerで開こうとすると、「ファイルが壊れています。」といったメッセージが出ます。

元ファイルとどのくらいファイルサイズが違っていますか?(元のファイルが100KBだとしたら何KBとか、そういう答え)
アップロードしたファイルの拡張子は.pdfとして保存できていますか?
KIDD さん返答ありがとうございます。

>upFilepdfには何を渡しているんですかね。
>呼び出し元が書いていないから、なおさらよくわかりません。

呼び出し元とはどこを書けばいいのですか?

フォームには直接PDFファイルを指定しています。(参照ボタンでファイルを選択)
また、フォームから書き込み処理に移動した先は以下の通りです。

-----------------------------------------------------
#----------------#
# ログ書込処理 #
#----------------#
sub regist {
# フォーム入力チェック
&form_check;

# 時間を取得
&get_time;

# クッキーを発行
&set_cookie;

# ファイルロック
if ($lockkey) { &lock; }

# ログを開く
open(IN,"$logfile") || &error("Open Error : $logfile");
@lines = <IN>;
close(IN);

# 記事NO処理
$top = shift(@lines);
($no,$ip,$time2) = split(/<>/, $top);
$no++;

# 連続投稿チェック
if ($addr eq $ip && $wait > $times - $time2)
{ &error("連続投稿はもうしばらく時間をおいて下さい"); }


# ファイル添付処理

if ($in{'upfile1'}) { &UpFile1; }
       〜
        〜
if ($in{'upfile10'}) { &UpFile10; }
if ($in{'upfilepdf'}) { &UpFilepdf; }
-----------------------------------------------------


>元ファイルとどのくらいファイルサイズが違っていますか?(元のファイルが100KBだとしたら何KBとか、そういう答え)
>アップロードしたファイルの拡張子は.pdfとして保存できていますか?

何個か試してみました。
アップ前→アップ後をFTPでDLし計測
704KB(721,081)→739KB(757,511)
63.7KB(65,307)→67.1KB(98,811)
518KB(530,762)→544KB(557,228)
全部増えてますね…
また、拡張子はすべてpdfとなっています。
オリジナルのファイルのデコード処理にて562行目付近で、アップロードされたファイル以外にタグ処理などを行っています。今回の改造処理でkeyにpdffileを追加したが、その内容もタグ処理のルーチンを通過したのではないでしょうか。(ので、サイズが増える)
KIDD さん返答ありがとうございます。

>今回の改造処理でkeyにpdffileを追加したが、その内容もタグ処理のルーチンを通過したのではないでしょうか。

その通りでした!!
デコード部分で、その他の画像ファイルは排除になっていたのに、そこにpdfフォームも排除としないといけなかったのを気がつかなかっただけでした。

無事解決できました。ありがとうございました!!
結果論ですが、はり付けたソースの部分には何の関係もなかったわけですよね。


他のトピでもいつもうるさく言ってますが、自分で勝手に範囲を決めてソースを貼るのはアドバイスをもらうときには避けるべき行為です。(見にくいし)

改造したコードをどこかのサーバにtxtでおくなりしましょう(パスワード等の見せたくない情報は伏せるなりして)

今回は元のソースをあたることができたので解決のための情報にあたりはつきましたが。。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

超初心者向けCGI講座 更新情報

超初心者向けCGI講座のメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。

人気コミュニティランキング