URL付のcgi を動かすにはどうしたらいいのでしょう。
つまり2つの独立したサーバーがあり、お互いに
呼び出して実行したい場合、同一サーバーなら通常、

$test= 'home/public_html/cgi/test.cgi';
open (test);
print while <test>;

ちょっとまどろっこしいんですが、このように実行
できるかと思うんです。
しかし、別のサーバーにあるとこうはかけません。
したがって1行目を

$test= 'http://test.com/cgi/test.cgi';

・・・と書きたいところなのですが、どうもうまく
実行されないようです。
何かいい解決策があれば教えてください。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

http: のスキームから始まるものは、当然プログラムという解釈ではないです。


HTTPというプロトコルを利用して、"ハイパー(Hyper)テキスト(Text)を転送(Transfer)する通信規約(Protocol)"なわけですから、そのサーバ上でプログラムが実行・解釈されて、そこからハイパーテキストを転送するだけです。
変数にそのプロトコルを利用するものを代入して、openしたって、Perlがそのプロトコルの手続きを代行してくれるものではありません。

「他のサーバのCGIを実行して、そこから排出されるハイパーテキストを取得したい」という事であれば、Socketモジュールでポート80番(http)への手続きを自分で行うか、LWPなどのモジュールを使用する必要があります。

恐らくLWP::Simpleを使用するのが一番簡単なので、

-----
use LWP::Simple;
$test= 'http://test.com/cgi/test.cgi';
getprint($test);
-----

で、恐らくご希望の動作が行えるはずです。
尚、LWP::Simpleは標準で使用出来るモジュールではないのでモジュールをインストールする必要があります。
(参考URLはLWPモジュールのダウンロード元)

Perl標準のSocketモジュールを使用する場合は

-----
use Socket;
my $test = 'http://master/';
my($host, $cgi) = ($test =~ m{^http://(.+?)(/.+)$});
my $osock =
sockaddr_in(scalar(getservbyname('http', 'tcp')),
scalar(gethostbyname($host)));

$| = 1;
socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
connect(SOCK, $osock);
send(SOCK, "GET $cgi HTTP/1.0\n\n", 0);
my $flag = 0;
while(<SOCK>){
$flag = 1 if /^[\r\n]+$/;
next unless $flag;
print;
}
close SOCK;
-----

こうすれば恐らく可能です(テストしていません)
ちなみに、

>$test= 'home/public_html/cgi/test.cgi';
>open (test);
>print while <test>;

では動かないはずです。

$test= 'home/public_html/cgi/test.cgi';
open (test, "$test |");
print while <test>;

なら動くとは思いますが…。

参考URL:http://search.cpan.org/search?dist=LWP5emu
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
大変詳細かつ、明確な説明感謝いたします。
このスクリプトを穴のあくほど十分に参考にさせて
いただきます。m(__)m

お礼日時:2002/02/18 19:36

すみません。

No.2のnipotanです。
回答後にコードを読んでいて間違いに気付いたので補足です…。

Socketを使う場合のコードにミスがありました。

>socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'));

という行は、正確には
socket(SOCK, PF_INET, SOCK_STREAM, scalar(getprotobyname('tcp')));
としないとダメかも知れません。

ちなみに、
>my $test = 'http://master/';
というのは、私の手元の環境で/etc/hostsに加えているローカルコンテンツのURLを書いてしまいました ^^;
$testという変数に、実行したいCGIのabsolute URIを代入すればOKです。
(テストしてみました)
    • good
    • 0
この回答へのお礼

Socket の方法と両方試してみたのですが、LWP::Simple
の方法であっさり動いたので、感激しました。
いい感じです。ありがとうございました!!!

お礼日時:2002/02/19 15:15

他サイトのCGIの呼び出しは,HTTP経由で行わなくてはなりません。


(そうでなくてはセキュリティ上問題がありすぎる)
逆にいえば,HTTP経由であれば可能ですが,そのためにはPerlからHTTPが扱えなくてはなりません。

その方法としては,

A)自分でプロセス間通信のプログラムを書く
B)どこかからHTTP通信を行うPerlモジュールを探しだしてくる

が考えられます。

A)については,Perlにはプロセス間通信のAPIが備わっているので,それを使えば良いでしょう。
B)については,どこかにはあると思いますが,私は知らないので,ご自分で探してみてください。

いずれにせよ,CGIがHTTPを経由してどのように動作するのかを理解している必要がありますので,まずHTTPやCGIの仕組みについて理解することをおすすめします(参考URLにいくつかそれらしいものを挙げておきましたが,これだけではたぶん不充分だと思います)。

参考URL:http://www.atmarkit.co.jp/fnetwork/rensai/netpro … http://www5a.biglobe.ne.jp/~n_rieko/cgi/init.htm
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
今朝になってもどなたからも回答がないので、多少
へこんでいたところでした。
しかもHTTP経由で行なうとは思いつきませんでした。
参考URLを十分に参考にさせていただきます。m(__)m

お礼日時:2002/02/18 19:26

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Q$wfurikae = 1 if ( &ccom::getShukujitsu( &com::tD( $wwy,$wwm,$wwd )) ne '' );がよく

$wfurikae = 1 if ( &ccom::getShukujitsu( &com::tD( $wwy,$wwm,$wwd )) ne '' );

というスクリプトがあったのですが、

$wfurikae = 1 の後に;もいれずifがきています。

違和感があります。

どのような意味になるのでしょうか。

宜しくお願い致します。

Aベストアンサー

そのまんまだと思いますよ。
if 以下の条件が真の時 $wfurikae = 1となります。
Perlはいろいろな書き方ができますので、こういう書き方もありです。
英語の文法の並びにする書き方です。

Qperlスクリプト s/^\s+//;  s/\s+$//;  return wantarray ? @out : $out[0]; について

自作の掲示板を作ろうと思い、perlの勉強をしている者です。人様の作ったスクリプトを解析しています。以下のスクリプトはライブラリに記述されていたものです。


sub tttt {
my @out = @_;
for (@out) {
s/^\s+//;
s/\s+$//;
}
return wantarray ? @out : $out[0];


このスクリプトなんですが、 s/^\s+//; の部分の「+」と s/\s+$//; の部分の「+$」、 また「return wantarray~」 の三つの部分のスクリプトが、どういった働きをしているの分かりません。専門書やウェブ上のリファレンスも色々調べたのですが・・。

分かる方いらっしゃいましたらご教授下さると幸いです。よろしくお願いします。

Aベストアンサー

まず前2つの「+」は,正規表現における,「直前の表現を一回以上繰り返し」をあらわします.
「\s」は空白文字一文字を表す正規表現ですので,「\s+」は,「一文字以上の空白文字」になります.
次に,最初の「^」と2番目の「$」は,その正規表現がどこに現れるかを示す記号です.それぞれ,先頭と最後尾にあることを示します.
したがって,「^\s+」は,「最初に空白が一文字以上ある文字列」に,
「\s+$」は「行末に空白が一文字以上ある文字列」にヒットします.
置換構文sはご存知なんですかね.すなわち,この2文で,行の最初と最後の空白を消しているんです.

次に, wantarray ですが,
http://www2u.biglobe.ne.jp/~MAS/perl/ref/wantarray.html
によると,このサブルーチンttttを呼び出すときに,何を返り値にしているかで真偽が決まる関数です.
呼び出す時に配列を希望していたら @out 全体を,変数を希望していたら $out[0]だけを返します.

QPrel正規表現で'$1$'.$saltのあたりが理解できない。

小生Perlを勉強中です。
Perl Codeに以下のようなパスワード暗号処理のサブルーチンが
ありましたが、読めません。教えて下さい。

sub encrypt{
local($inpw)=$_[0];
local(@SALT,$salt,$encrypt);

@SALT=('a'..'z','A'..'Z','0'..'9','.','\');
srand;
$salt=$SALT[int(rand(@SALT)).$SALT[int(rand(@SALT))];
$encrypt=crypt($inpw,$salt)||crypt($inpw,'$1$'.$salt);
return $encrypt;
}

とあります。
特に、下から3行目の($inpw,'$1$'.$salt)が
理解できません。
解説していただければ幸いです。

Aベストアンサー

過去に同様の質問がありました。ctpsysさんの疑問にすべて答えられるかどうかわかりませんが、すくなくとも
>下から3行目の($inpw,'$1$'.$salt)が理解できません
というご質問に対しては参考になるかと思います。

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=74593,http://oshiete1.goo.ne.jp/kotaeru.php3?q=74593,

QCGI.pmで'&'が'&'に置き換わってしまう!

文字「&」を出力したいのにCGI.pmが自動的に「&amp;」に変換してしまいます。

具体的には、
<a href="abc" accesskey="&">abc</a>
のような文字列を出力させるために、
print($q->a({-href => 'abc', -accesskey => '&'}, 'abc'))
というコードを実行したのですが、
出力される文字列は、
<a accesskey="&amp;" href="abc">abc</a>
のように「&」が自動的に「&amp;」に置き換わってしまいます。

これの解決策として、オブジェクトを使用せずに、直接CGI.pmのメソッドを呼び出すと、なぜか変換されません。
すなわち、上のコードの「$q」の部分を「CGI」として、
print(CGI->a({-href => 'abc', -accesskey => '&'}, 'abc'))
とします。

これは何か意味があるのでしょうか。それともただのバグ?
直接CGI.pmのメソッドを呼び出さなくても解決する方法はありますか。

accesskeyに関するご意見は、先日質問したこちらのスレへ頂けるとうれしいです。
http://oshiete1.goo.ne.jp/qa5707867.html

文字「&」を出力したいのにCGI.pmが自動的に「&amp;」に変換してしまいます。

具体的には、
<a href="abc" accesskey="&">abc</a>
のような文字列を出力させるために、
print($q->a({-href => 'abc', -accesskey => '&'}, 'abc'))
というコードを実行したのですが、
出力される文字列は、
<a accesskey="&amp;" href="abc">abc</a>
のように「&」が自動的に「&amp;」に置き換わってしまいます。

これの解決策として、オブジェクトを使用せずに、直接CGI.pmのメソッドを呼び出すと、なぜか変換されま...続きを読む

Aベストアンサー

えぇと, #2 の参考にあげた URL を読んでいただけるとありがたいのですが,
Certain attributes call for a single character from the document character set. These attributes take the %Character type in the DTD.

Single characters may be specified with character references (e.g., "&amp;").
とあります. 最後の 1文を読めば分かるように, 「1文字」であっても文字実体参照を使うことは仕様上可能です.

Q$ENV{'HTTP_COOKIE'}は例えば

a=x;b=y;c=z;
のようなフォーマットになっているのでしょうか?
そうすると
自分のサイトが使っているクッキー名と
他のサイトが使っているクッキー名が偶然に一致していたとき
あるブラウザに書かれている自分のサイトのクッキーが
そのブラウザが他のサイトをアクセスしたときに上書きされてしまうのでしょうか?
そのためにクッキー名をつけるときには偶然に一致しないように一定の長さ以上で特異な名前にしたほうがいいのでしょうか?
クッキーについて基本的なことを教えてください

Aベストアンサー

Cookieは、ドメインごとに設定され、パスで出力先が限定されます。パス指定されない場合、ドメインのルートパスとなります。

おっしゃる通り、同一ドメイン内で設定されたCookieが、全てHTTP_COOKIEで取得出来ます。(無論ドメインが違うと駄目。)もしも、Cookieにパス指定がある場合は、そのパス以下では該当のCookieが取得可能、それ以上の階層では取得不可能になります。(デフォルトだとルートパスなので、ドメイン内のどの階層でも取得可能です。)

このような仕様の為、同一ドメイン・パス指定以下の階層で利用されるものでは、偶然一致してしまうと、他のクッキーを上書きしてしまう可能性はあります。他と重複しない用に、プログラム名等を含ませる形で名付けてあげると良いでしょう。また、共用サーバなどでは、パス指定で自分のホームを指定しておき、他の方のクッキーと混同されないようにする、等の配慮が必要になります。


おすすめ情報