• ベストアンサー

txtデータをhtmlに表示してくれるCGI

例えばサーバー上にA.txt、B.txt、C.txt・・・とあったとします。 でこれをブラウザでhttp://***.***.jp/A.txt(例)というような感じで呼び出せるCGIはありませんか? 呼び出しURLは別にhttp://***.***.jp/***.cgi?A.txtなどとなってもかまいません。

質問者が選んだベストアンサー

  • ベストアンサー
  • zebedeer
  • ベストアンサー率66% (80/121)
回答No.8

httpdのエラーログに関してはサーバの管理者へ問い合わせてください。 (サーバOS、httpd、諸々設定によって一概には言えないので) 何か問題が起こってhttpdのエラーログが参照できない場合、以下の部分を編集することによって詳細なエラーを表示することが出来ます。 (エラーの確認が終わったら元に戻すことをお勧めします) sub error { print "Content-type: text/html\n\n"; print <<"END_HTML"; <html> <head><title>error</title></head> <body> $_[0]<br> $! </body> </html> END_HTML die; } #「$!」の部分が詳細なPerlのエラーメッセージに変換されます。

その他の回答 (7)

  • zebedeer
  • ベストアンサー率66% (80/121)
回答No.7

そう言えばhtmlなかったですね。 足してみます。 エラー時にもhtmlが表示されますが、詳しい内容はhttpdのエラーログを確認してください。 (セキュリティ上、詳細なエラーメッセージをユーザへ返しません) #!/usr/bin/perl my $path = './'; my ($file) = $ENV{'QUERY_STRING'} =~ /(\w+\.\w+)$/o; opendir (DIR,$path) or &error ('opendir'); my %dir = map {$_,$_} grep !/^(?:\.|\.\.)$/o,readdir (DIR); closedir (DIR); open (IN,'< '.$path.$dir{$file}) or &error (open'); print "Content-type: text/html\n\n"; print <<"END_HTML"; <html> <head><title>$dir{$file}</title></head> <body> END_HTML {local ($/) = undef;print <IN>;} print <<"END_HTML"; </body> </html> END_HTML close (IN); sub error { print "Content-type: text/html\n\n"; print <<"END_HTML"; <html> <head><title>error</title></head> <body> $_[0] </body> </html> END_HTML die; }

nyandane
質問者

補足

すみません。 >詳しい内容はhttpdのエラーログを確認してください。 どうやってやればよいのでしょうか?

  • zebedeer
  • ベストアンサー率66% (80/121)
回答No.6

No.1~No.3に挙げられているコードはセキュリティ上大きな問題があるので、外部から実行可能な場所へ設置するのは大変お勧めしません。 (CGI実行ユーザで閲覧可能な、サーバ上の全ての情報が閲覧できます) 以下のコードならとりあえず上記の問題はありません(多分) 文字コードはサーバ上に保存されている文字コードのまま出力されます。 ファイル名は半角英数と_(アンダーバー)、拡張子用の.(ドット)をひとつだけ含めることが出来ます。 (***.cgi?aaa.txtや***.cgi?bbb.txtと呼び出すことを想定) そのまま設置した場合、***.cgi?***.cgiと呼び出すことで自分のファイル内容が表示されてしまいます。 (セキュリティ上問題になる場合があります) この問題を回避したい場合、「$path = './';」を表示したいファイルの保存されたディレクトリに変更し、表示するファイル群をそのディレクトリ内に保存してください。 #!/usr/bin/perl my $path = './'; my ($file) = $ENV{'QUERY_STRING'} =~ /(\w+\.\w+)$/o; opendir (DIR,$path) or die; my %dir = map {$_,$_} grep !/^(?:\.|\.\.)$/o,readdir (DIR); closedir (DIR); open (IN,'< '.$path.$dir{$file}) or die; print "Content-type: text/html\n\n"; {local ($/) = undef;print <IN>;} close (IN); あと、「http://***.***.jp/A.txt」のような形式で呼び出す方法として、 たとえばcgiを拡張子無しで呼び出せるように設定し、 「/aaa/bbb/cgi_file_name/A.txt」とする方法もあります。 (この場合、cgi_file_nameというcgiへ/A.txtが渡される)

nyandane
質問者

補足

zebedeerさんご回答ありがとうございます。 zebedeerさんのcgiを実行してみました。 ***.cgi?a.txtで呼び出してみたところ、 エラーは出ないのですがページが真っ白です・・・。 もしかして、htmlの記述をしなければならないのでしょうか?

  • sisya
  • ベストアンサー率39% (97/244)
回答No.5

cgiの呼び出しを省略する方法として .htaccessと言うファイルを作成して そのファイルに 「DirectoryIndex ***.cgi」と記述して下さい。 (***は実際のファイル名に置き換えてください) そうすると http://***.***.jp/?A.txt とよびだしてやれば http://***.***.jp/***.cgi?A.txt を指定した事と同じ事になり、 cgi名を書かなくても実行できます。 後、unixでは大文字小文字を区別するので、 「A.txt」と「a.txt」を別のファイルとして認識します。 一見正しくファイルを指定しているつもりでも 間違っている場合がありますので注意してください。

nyandane
質問者

補足

早速やってみたのですが、 やはり表示できません・・・。 >「DirectoryIndex ***.cgi」と記述して下さい。 .cgiの後には改行を入れるということでいいんですよね?

  • Dpop
  • ベストアンサー率51% (279/544)
回答No.4

disp.text.cgi は typo です。disptext.cgi などと言う名前で保存し、disptext.cgi?filename.txt で表示です。 簡単なものですが、動作テストもやってあるので、設定さえ正しければ動作するはずです。 「ファイルがありません」エラーって言うのは、Jcode.pm が無い可能性が高そうな気がします。(jcode.pl ではなくて、Jcode.pm を使いました。) use Jcode; の行を、 require 'jcode.pl'; に変更して下さい。また、 Jcode::convert(\$s,'euc'); の行を、 jcode::convert(\$s,'euc'); に変更して下さい。 または、Jcode.pm をインストールして見てください。 これでOKじゃ無いかなぁ~ と思います。

  • Dpop
  • ベストアンサー率51% (279/544)
回答No.3

#2 です。 decode 関数は使用していなかったです(^_^;) 失礼! #!/usr/bin/perl use Jcode; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buf, $ENV{'CONTENT_LENGTH'}); } else { $buf = $ENV{'QUERY_STRING'}; } if (-f $buf) { print "Content-type: text/html\n\n"; print <<"END_HTML"; <html> <head><title>$buf</title></head> <body> END_HTML open(IN, $buf); while(<IN>) { chop; $s = $_; Jcode::convert(\$s,'euc'); $s =~ s/&/&amp;/g; $s =~ s/"/&quot;/g; $s =~ s/</&lt;/g; $s =~ s/>/&gt;/g; $s =~ s/ /&nbsp;/g; print $s. "<br>\n"; } close(IN); print <<"END_HTML"; </body> </html> END_HTML } else { print "Content-type: text/html\n\n"; print <<"END_HTML"; <html> <head><title>not found $buf</title></head> <body> not found $buf. </body> </html> END_HTML } exit(0);

  • Dpop
  • ベストアンサー率51% (279/544)
回答No.2

#1 です。 やはり、バグってました(笑) 修正して置きました。ご要望の様に、***.cgi?a.txt で表示されます。 例えば、disp.text.cgi とでも名前を付けて保存して頂き、disptext.cgi?a.txt などとして見て下さい。 #!/usr/bin/perl use Jcode; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buf, $ENV{'CONTENT_LENGTH'}); } else { $buf = $ENV{'QUERY_STRING'}; } if (-f $buf) { print "Content-type: text/html\n\n"; print <<"END_HTML"; <html> <head><title>$buf</title></head> <body> END_HTML open(IN, $buf); while(<IN>) { chop; $s = $_; Jcode::convert(\$s,'euc'); $s =~ s/&/&amp;/g; $s =~ s/"/&quot;/g; $s =~ s/</&lt;/g; $s =~ s/>/&gt;/g; $s =~ s/ /&nbsp;/g; print $s. "<br>\n"; } close(IN); print <<"END_HTML"; </body> </html> END_HTML } else { print "Content-type: text/html\n\n"; print <<"END_HTML"; <html> <head><title>not found $buf</title></head> <body> not found $buf. </body> </html> END_HTML } exit(0); sub decode { my($buf, %in); if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buf, $ENV{'CONTENT_LENGTH'}); } else { $buf = $ENV{'QUERY_STRING'}; } foreach (split(/&/, $buf)) { ($key, $val) = split(/=/); $val =~ tr/+/ /; $val =~ s/&/&amp;/g; $val =~ s/"/&quot;/g; $val =~ s/</&lt;/g; $val =~ s/>/&gt;/g; $val =~ s/\0//g; $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $in{$key} .= "\0" if (defined($in{$key})); $in{$key} .= $val; } (%in); }

nyandane
質問者

補足

ご丁寧な対応ありがとうございます。 >disp.text.cgi とでも名前を付けて保存して頂き、disptext.cgi?a.txt などとして見て下さい。 ということですが、「disptext.cgi?a.txt」で呼び出すと「ファイルがありません」エラーになってしまい、 試しに保存したとおりの名前「disp.text.cgi」で呼び出すとcgi構文エラーになってしまいます。 パラメータは755、jcode.plもインストールしているのですが・・・。

  • Dpop
  • ベストアンサー率51% (279/544)
回答No.1

うぅ~ん なんとなく、こんな感じかな。。。 ※1 デバックしていません(^_^;) 多分、こんな感じで動くと思います。バージョンです。 ※2 ***.cgi?a.txt ではなくて、***.cgi?file=a.txt って形式にしました。(面倒だったので。) ※3 2バイト文字は、日本語EUCで表示しています。 #!/usr/bin/perl use Jcode; %in = &decode(); if (-f $in{'file'}) { print "Content-type: text/html\n\n"; print <<"END_HTML"; <html> <head><title>$in{'file'}</title></head> <body> END_HTML open(IN, $in{'file'}) { while(<IN>) { chop; $s = $_; Jcode::convert(\$s,'euc'); $s =~ s/&/&amp;/g; $s =~ s/"/&quot;/g; $s =~ s/</&lt;/g; $s =~ s/>/&gt;/g; $s =~ s/ /&nbsp;/g; print $s. "\n"; } close(IN); print <<"END_HTML"; </body> </html> END_HTML } } exit(0); sub decode { my($buf, %in); if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buf, $ENV{'CONTENT_LENGTH'}); } else { $buf = $ENV{'QUERY_STRING'}; } foreach (split(/&/, $buf)) { ($key, $val) = split(/=/); $val =~ tr/+/ /; $val =~ s/&/&amp;/g; $val =~ s/"/&quot;/g; $val =~ s/</&lt;/g; $val =~ s/>/&gt;/g; $val =~ s/\0//g; $val =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $in{$key} .= "\0" if (defined($in{$key})); $in{$key} .= $val; } (%in); }

関連するQ&A