• ベストアンサー

perl パラメータ

このようなソースがあります。 require "test.cgi"; これはperlを読み込めますが、 require "test.cgi/path"; としますと、500Errorです。 .cgiの後ろのPATH_INFOをrequireで読み込むperlのパラメータとして渡す方法はありますか。

  • Perl
  • 回答数6
  • ありがとう数0

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

  • ベストアンサー
  • wormhole
  • ベストアンサー率28% (1620/5655)
回答No.6

#1です。#2の補足からすると >require "/Users/$FORM{'directory'}/Sites$ENV{'REDIRECT_URL'}"; /Users/$FORM{'directory'}/Sites$ENV{'REDIRECT_URL'}" のパスのファイルがOS上の何かのコマンドで、それが危険なものかどうかを察知しようとしていますか? もし、そういう事であれば、apacheの設定でurlのパスとOSのパスで、そういうものをマッピングしなければいいだけに思えるのですけど。

humu01jp
質問者

補足

URL上でリクエストのあったファイルをopenして、ソースコード中にsystem関数があったら、エラーを文を表示し、なければ通過してリクエストされたファイルを読み込んで表示させる、といったことですね。 いろいろいじくって、リクエストされたファイルのソースコードでPATH_INFOの記述でURL上のPATH_INFOは取得できるようになったのですが、今度はQUERY_STRINGがエラーを吐きます。 *.cgi?aaaというのはエラーが出ますが、*.cgi/path?aaaの場合はなぜか表示できます。

その他の回答 (5)

回答No.5

もともとの問題とは別件なのかな・・ 単に、test.cgi/pathからpath部分を取り出したいということでなく Webサーバー(Apache)がtest.cgiとpathに切り分けされる前に リダイレクトされてるからPATH_INFOにセットされてない ってことですね。 $ENV{'REDIRECT_URL'} =~ s/\.cgi\/([\w|\!\#\&\=\-\%\@\~\;\+\:\.\?\/]+)$/\.cgi/g; としているのは、環境変数REDIRECT_URLに Webサーバー側でリダイレクト等されたときに設定されて これはブラウザからのもともとのURLがtest.cgi/pathのように PATH_INFO設定されたURLでも、そのままtest.cgi/path のままで になりますね。 そこで、この正規表現では、 *.cgiのあとの文字を取り消して cgiファイル名部のみにしてるということですね。 この場合、サーバー上にtest.cgiはあるけどtest.cgi/pathは存在をしないでので PATH_INFOに/pathをセットするということを apacheはしてくれないので その正規表現の切り取った部分のほうをPATH_INFOの変わりに使うしかないでしょう。

humu01jp
質問者

補足

PATH_INFOは解決できましたが、こんどはQUERY_STRINGで詰んでます。 *.cgi/path?*は表示できますが、*.cgi?*はエラーを吐きます。

回答No.4

私の説明がわるかったのか、 根本的に勘違いされているようです。 perlには、require "test.cgi/path"; のよう書いてINFO_PATH値を引き渡す機能はありません。 この書き方をすると test.cgiというディレクトリのしたのpathというファイルを 呼び出ししにいくだけです。 (ファイルが存在しない場合は、500エラーとかになりますね) ではなぜ、ブラウザでURLとして function.cgi/pathと指定することで CGIとして、function.cgi を呼び出て それにINFO_PATHとして"path"を渡せているかというと それはWebサーバーがそのように内部処理してくれているからです。 Webサーバーから CGI呼び出しで function.cgi に渡されたあとは Webサーバーを経由しないでperlのみの環境で動いている訳ですから、 perlでrequre('test.cgi/path'); と書いても、 perlはtest.cgiを呼び出してくれないわけです。 親CGIのfunction.cgiから 子側のtest.cgiをrequireで呼びたいのなら function.cgiでは、require('test.cgi');(pathなし) で呼び出すしかなく pathの実際の値を引き渡したいなら、 test.cgi側でfunction.cgiで作った変数なり Webサーバーがセットしてくれた 環境変数を使うしかありません。 ようするに、test.cgiは function.cgiから呼ばれる 単なるサブルーチンとしてつくる形ですね。

humu01jp
質問者

補足

そこでエラーを出ないようにやってみたのが。 $ENV{'REDIRECT_URL'} =~ s/\.cgi\/([\w|\!\#\&\=\-\%\@\~\;\+\:\.\?\/]+)$/\.cgi/g; ところが、これをやってしまうと、呼び出し先のCGIで$ENV{'PATH_INFO'}とやっても表示できないのです。 REDIRECT_URLはapacheのmod_rewriteを使ってリダイレクトしてるので、リダイレクト元のパスを取得するためですね。 下の方の回答でスクリプトを書いてますので、ご確認いただけると幸いです。 そもそも、 リダイレクトせずにapache側で文法をチェックできればいいのですが……。

回答No.3

あ、ごめんなさい。日本語おかしかったですね。 > URL中のGETパラメータは、そのままでCGIがコールされるのではなくて >Webサーバーから環境変数QUERY_STRINGにされて >で渡されるので、CGI側ではそれを使います。 ↓ URL中のGETパラメータがそのままCGIに渡されているのではなく Webサーバーで環境変数QUERY_STRINGにセットされてから 渡されるので、CGI側ではその環境変数を使って動作させます。 でした。 しかも、今回の問題はGETパラメータでなくPATH_INFOですね。 ただ、PATH_INFOも、環境変数名がPATH_INFOになるだけで 考え方は同じです。 つまり、ブラウザからURLとしてtest.cgi/path で渡されると Webサーバーは、環境変数PATH_INFOに /pathをセットしてから test.cgiをCGIコールしています。 (test.cgi/pathというファイル名で実行している訳ではないことに注意) よって、CGIからCGIをシステムコールで呼で出す場合は、 これを模擬する必要があります。 しかし、requireで呼び出すのであれば、 CGIとしてコールしていのではなくサブルーチン実行のようなものなので 渡したい値は、サブルーチンの引数にするとかグローバル変数にしておけばそのまま渡せます。 つまり (1) 出来合いのCGIを呼び出したいが、それを改造することが難しいのなら 親側のCGIで環境変数代入と子側のCGIのコールをセットにして システムコールする方式 (2) 自作のCGIをrequire で呼ぶなら、test.cgi側では GET/POST/PATH_INFOの値は使わずに 親側から変数をもらって動作するように改造する方式 のどちらかになるでしょう。

humu01jp
質問者

補足

すみません、言葉足らずでした。 test.cgiを呼び出すCGIをfunction.cgiとし、function.cgiではtest.cgi(.cgi拡張子のperlなら別のファル名でもいい)の文法で特定の文字列、例えばsystem関数とかがあったらfunction.cgi側でエラーメッセージを出し、問題がなければ通過して、読み込みたいtest.cgiをブラウザ上で実行したいです。この時に、URL上でtest.cgi/pathとしても、test.cgi内で$ENV{'PATH_INFO'}で表示したくても、何も代入されず、逆にfunction.cgi側でtest.cgi/pathとしてしまうと、500エラーが返されるわけです。

回答No.2

URL中のGETパラメータは、そのままでCGIがコールされるのではなくて Webサーバーから環境変数QUERY_STRINGにされて で渡されるので、CGI側ではそれを使います。 つまり、cgiから別のcgiをシステムコール (system()とかpopenとか)するなら 親側とは、別プロセスになるのでGETパラメータにしたいものは 環境変数QUERY_STRINGにセットしてからシステムコールするという工夫が必要です。 しかし、今回のはrequire()で呼ぶ形で実行できるCGIのようなので それならサブルーチンで実行するようなものなので 同じプロセス内なので、親側のグローバル変数なりを test.cgi内でそのままつかえばよいのでは?

humu01jp
質問者

補足

下記、スクリプト。 引っかかってるのは、たぶん「$ENV{'REDIRECT_URL'} =~ s/\.cgi\/([\w|\!\#\&\=\-\%\@\~\;\+\:\.\?\/]+)$/\.cgi/g;」だけど、これないとrequireでエラー出るし、ここの部分を直すにしてもどういう文法にすれば見当がつかずでして。 #!/usr/bin/perl require "./jcode.pl"; &decode; sub decode { if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/,$buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $buffer =~ tr/+/ /; $buffer =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; &jcode'convert( *value, 'utf8' ); $FORM{$name} .= $value; } } $ENV{'REDIRECT_URL'} =~ s/\.cgi\/([\w|\!\#\&\=\-\%\@\~\;\+\:\.\?\/]+)$/\.cgi/g; open(ERROR, "/Users/$FORM{'directory'}/Sites$ENV{'REDIRECT_URL'}"); @error = <ERROR>; foreach (@error) { if($_ =~ /system\(/){ print "Content-type: text/html\n\n"; print <<"EOM"; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>強制停止</title> </head> <body> <center>システムが危険な関数を検知したので、プログラムを強制停止しました。</center> </body> </html> EOM exit; } } require "/Users/$FORM{'directory'}/Sites$ENV{'REDIRECT_URL'}"; exit;

  • wormhole
  • ベストアンサー率28% (1620/5655)
回答No.1

ないです。 require は指定のパスにあるファイルをperlのプログラムが書かれたファイルとして読み込み機能ですから require "test.cgi/path"; test.cgiディレクトリにあるpathというファイルを読込むだけです。

humu01jp
質問者

補足

では、test.cgi/pathをtest.cgiとして読み込んでくれ、かつ/pathの部分をPATH_INFOとして出力できる関数はありますか?

関連するQ&A

  • perl/cgiでjpeg画像のクリック座標をcgiパラメータに渡すには

    perl/cgiで表示したjpegの画像のクリックした点の座標位置を次にジャンプするページにcgiパラメータとして渡したいのですがどのようにすれば良いでしょうか?画像全体を<input type="button" src="画像ファイル" name="$test" value="返答">のようにすればよいのかもしれませんが、座標をパラメータ渡しする方法がわかりません。perl/cgiだけでは無理であれば、javascriptでcgiに渡すためのヒントでも構わないのですが。。。 ご存知の方がいたらご教示ください。

    • ベストアンサー
    • CGI
  • perlで受取ったパラメータをバイトコードのまま変数に代入

    HTMLフォームの、name=aのテキストボックスに「あ」と入力しCGIにSubmitすると、a=%82%A0とバイトコードに変換されわたされますよね 受け側のCGIで下記の様にそのパラメータを$aに代入すると、$aには「あ」となって代入されるのですが、あえて「あ」ではなくバイトコードの「%82%A0」で代入するようにするには、どうしたらよいのでしょうか? #!/usr/local/bin/perl require 'cgi-lib.pl'; require 'jcode.pl'; &ReadParse; $a=$in{'a'};

    • ベストアンサー
    • Perl
  • Perl require 共通の変数 外部ファイル

    ファイルが多くなってきて、その中でも共通の変数があるので 外部ファイルにまとめたい・・・ ~test.pl~ #!/usr/bin/perl require("testcommon.pl"); print qq(Content-type: text/html\n\n); print <<END; <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=$CHARSET"> <title>外部CGIファイル読み込み</title> </head> <body> END print qq($test<br>$data<br>$NEW); print <<END; </body> </html> END exit; 1; ~testcommon.pl~ #!/usr/bin/perl $test = "テスト"; $data = "テストです"; $CHARSET = "UTF-8"; $NEW ="サーバー"; 1; まずこれが現在テスト中で サーバーAでは、これでいけているのですが、 サーバーBでは、これではいけず、 エラーログを見ると 「@INC~/usr/local/lib64/perl5~」 とでてます。これがどのような意味をささしているのかわからないです。 いつも1行目に書く「#!/usr/bin/perl」の部分を書き換えてみたのですが・・・ さらにサーバーBでは、ログファイルなど開く際、フルパスでないと開けません。 require("testcommon.pl");←これですと インターネットサーバーエラーとなってしまいます。 これはエラーログを見るとフルパスで指定と書いていたので、 require("/path/path/path/testcommon.pl"); のようにしました。 これで、一応表示はできたのですが、 testcommon.plで新しい変数を書き加えると、($NEW123 = "追加したい変数";) 表示されません。 またCHARSETでUTF-8を指定してますが、 更新や、再度ページに入ったりすると、 CHARSETの変数が反応していなかったりしています。ページでソースを確認すると 変数の部分が空欄になってます。 これは require("/path/path/path/testcommon.pl"); が読み込んでいなかったり読み込んでいたり もしくは、一度なにをしたのかわからないですが、このフルパスの場所に testcommon.plのファイルをおいて、そのときのままになっている など、原因、対処がわからず困っております。 ※というより結論としては、 共通の変数を1つのファイルでしようしたいということです。 ~common.pl~ $a = 123; $b = "テスト"; $c = 2; ~test1.pl~ $TEST = $a * $c; print "$b$TEST\n"; #結果「テスト246」 ~test2.pl~ $TEST123 = $a + $c; print "$TEST123$b; #結果「125テスト」 このような感じ・・・(+_+)

  • ある書籍で、見つけました、perlのソースについて

    ある書籍で、見つけました、perlのソースについて 疑問がありまして、お尋ねします。 ※下記は、perl/cgiソースの一部です。 ある書籍で見つけたものです。 >require 'cgi-lib.pl'; >&ReadParse(¥%test); 私は、(%test)だと思っているのですが。 ()の中の、先頭に「¥」を付けることに、どのような意味 があるのでしょうか >$test = $test{'test'}; 仮に、$testの値が「"<&>"」だったとしまして、以下 をごらん頂きたいのですが、 >open(ファイルハンドル,$fname) >while(<ファイルハンドル>){ >$test =~ s/¥"/¥&quot¥;/g; 私の認識では、「s/"/&quot;/g;」ではと思うのですが、 「¥」はどのような意味なのでしょうか 以下、3行も同じ疑問です。 >$test =~ s/&/\&testmp\;/g; >$test =~ s/¥</¥&lt¥;/g; >$test =~ s/¥>/¥&gt¥;/g; >print $_; >} 書籍で上記のソースを見たのですが、 HTMLのフォームのテキストボックスに、「"<&>"」と入力し submitボタンで、上記コードを含む、cgiを開きます。 そして、「"<&>"」を受取っても正しく、置換し、 cgiから、HTML($fname)を開くプログラムです。 置換後のHTMLファイルには、「"<&>"」と表示されます。 以上、よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • Perlのモジュールについて

    perlで自作モジュールを作成したいのですが、どのように作成したらよいのでしょうか? 単にPackegae [モジュール名]; sub test{ ... } で Test.pmとすれば、モジュールとして使えますか? カレントディレクトリにrequire 'Test.pm'; とするとエラーになります。 あと、Perlだけで書いたモジュールとXS?で記述したモジュールは 基本的に同じものでしょうか?

    • ベストアンサー
    • Perl
  • perl CGIでの@INC

    たびたびお世話になります。 perl CGIを作っています。作っているCGIとは別のディレクトリにあるファイルをrequireしたいのですが、リモートログインできないレンタルサーバのため@INCのいじり方がわかりません。 こういった場合のrequire方法(あるいはプログラム再利用方法)をお教えください

    • ベストアンサー
    • Perl
  • mod_rewriteについて

    Apacheのmod_rewriteを使って、aaa.cgiをいったんbbb.cgiにリダイレクトし、aaa.cgiの危険な関数を確認するためにソースコードをopen関数でチェックして、 問題がなければ、requireを使って$ENV{'REDIRECT_URL'}でaaa.cgiを読み込んであげるのですが、前者も後者もaaa.cgi/pathというようなPATH_INFOつきのアドレスだと、500 Internal server errorになってしまって表示できないのですが、解決方法はありますか? レンタルサーバー用のチェックシステムなんです。

    • 締切済み
    • CGI
  • perlによる外部プログラムの実行

    perlにてCGIを作成しています。 ブラウザでCGIにアクセスしたとき、gpgというコマンドプロンプトの プログラムを実行したいと考えており以下のようなプログラムを作成しました。 test.batを単体で実行したときにはうまく動作するのですが、CGIを介して 実行するとうまくいきません。 CGIのプログラム (WriteCmd.cgi) **********************************  #!c:/Perl/bin/perl  print "Content-type: text/html\n\n";  print "test.batの実行\n<br>";  system("test.bat");  exit; ********************************** test.bat **********************************  gpg --batch --gen-key sample.txt ********************************** またtest.batの内容を **********************************  mkdir test ********************************** としてみるとディレクトリがちゃんと作成できるので WebサーバやPerlのパスの問題ではないと考えております。 よい解決方法がありましたら教えていただけると助かります。 よろしくお願いします。

    • ベストアンサー
    • CGI
  • biglobeでperl利用

    biglobeのホームページにcgiを置きたいです。 GsMonというフリーのスケジューラーを設置したいのですが、 既にローカルサーバーでのテストはできています。 GsMon http://www17.ocn.ne.jp/~seiko/ Biglobeサポート http://homepage.biglobe.ne.jp/manual/shiyou/index.html より CGIの呼び出し方 http://www**.biglobe.ne.jp/~ホームページアカウント/xxxxx.pl 利用可能なコマンド 実行パス perl /usr/local/bin/perl とありますが インストール、初期設定時の画面で データディレクトリ (/user など) CGIの実行ディレクトリ (/Gsmon や CGIの呼び出し方[.pl]など実行ファイルは設定してない) ドキュメントルートからのパス の書き方がわかりません。 相対パスやHttpを含むパスを入れてみたのですが500エラーが出てしまいます。 biglobe側もCGIはサポート対象外ですし困ってます。

  • cgi(perl)でパラメータが渡せない

    以下のプログラムでnum=9が伝わらないので、ミスをご指摘ください。 グラフィカルなアクセスカウンタを表示させようとしていますが うまくいかないのでテキストモードでデバッグしています。 [ /usr/local/apache2/htdocs/gif-view.html ] <html> <head> <meta http-equiv="Content-type:" content="text/html; charset=UTF-8"> <title>gif-view</title> </head> <body> <iframe src="/cgi-bin/gif-test.cgi?num=9"></iframe> <!-- <img src="/cgi-bin/gif-test.cgi?0" width=50 height=50> --> </body> </html> [ /usr/local/apache2/cgi-bin/gif-view.cgi ] permission は 755 にしています。 #!/usr/bin/perl print "Content-Type: text/plain;\n\n"; print "gif-test.cgi\n"; $prm0 = @ARGV[0]; if($prm0 = "") { print "Param is exist\n"; } else { print "Param is empty\n"; 実行結果として gif-test.cgi Param is empty となります。 httpd.conf で Script Alias /cgi-bin/ "/usr/local/apache2/cgi-bin/" を有効にしています。

    • ベストアンサー
    • Perl

専門家に質問してみよう