CGIからCGIを呼ぶ際、POSTでデータを渡す方法は?
[上に]
[前に]
[次に]
フシギダネ
2000/03/18(土) 16:12:51
CGIからCGIを呼ぶ際に、
URL表示部に引数(aaa.cgi?passwd=aaa等)を表示させたくありません。
print "Location: ・・・・・ とする場合は、?の後に引数を記述しないとだめですよね。
text/htmlで出力して、POSTで引数を渡して実行するようなjavascriptを書いてもhistoryに残ってしまうし。
うーん。困りました。
どなたか助けて下さい。
andi
2000/03/18(土) 17:46:17
../199912/99120339.htm
びーだま
[E-Mail]
2000/03/18(土) 18:38:41
ソケット通信を使えば、解決できます。
Webクライアントをエミュレートしてあげればよいわけですね。
下記にソケットで、HTTP をしゃべって POST メソッドで要求
を出すクライアントのサンプルを掲示します。
おまけとして、User-Agent の指定の仕方も書いていますが、
これをやっておくと1つ良いことがあります。
受け側の CGI がこの CGI の呼び出しからしか反応しないようにするのに、
ここで、オリジナルな USER_AGENT を設定してあげることで 受け側
では、HTTP_USER_AGENT を利用して挙動を変えることが可能です。
#!/usr/local/bin/perl
use Socket;
$HOST = 'foo.bar.com';
$PORT = '80';
$FILE = '/cgi-bin/aaa.cgi';
$TIMEOUT = '10';
$QUERY = 'passwd=aaa&bbb=ccc'; # 適当に入れてください。
http_post($HOST, $PORT, $FILE, $QUERY);
exit;
#
sub http_post($$$$) {
my($host, $port, $file, $query) = @_;
my($ret) = _open_tcp($host, $port);
my(@list);
my($len) = length($query);
if ($ret == 1) {
# HTTP 要求ヘッダー
# POST メソッドで要求します。
# ここを GET にすると、普通のブラウザみたいにすることも出来ますね。
print SOCK "POST $file HTTP/1.0" . "\r\n";
# ここで適当な USER AGENT を設定させることが出来る。
# とりあえず、この場合は、環境変数をそのまま入れてみる。
print SOCK "User-Agent: $ENV{'HTTP_USER_AGENT'}" . "\r\n";
# Content-Length: を送る(クエリーのバイト数)
print SOCK "Content-Length: $len" . "\r\n\r\n";
# ヘッダーの最後は2回改行するのを忘れないように!
# POST したいならば
print SOCK "$query";
# タイムアウトアラーム開始
$SIG{'ALRM'} = \&_socket_timeout;
alarm($TIMEOUT);
# ボディー部
$flg = 0;
while(<SOCK>){
#*******************************************#
# ここで、受信した内容についてあれこれする。#
#*******************************************#
}
# タイムアウトアラーム解除
alarm(0);
# ソケットを閉じる
close(SOCK);
}
}
# TCPソケットのオープンと接続
sub _open_tcp($$) {
my($host, $port) = @_;
my($ret) = 1;
# ソケットのオープン
if (!socket(SOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp'))) {
$ret = -1;
}
# ポートへの接続
if (!connect(SOCK, sockaddr_in($port,inet_aton($host)))) {
close(SOCK);
$ret = -2;
}
# ソケットのバッファリングを停止
select(SOCK);
$| = 1;
select(STDOUT);
return $ret;
}
# ソケット通信タイムアウト時の処理
sub _socket_timeout {
close(SOCK);
exit;
}
1;
フシギダネ
2000/03/18(土) 20:24:07
ありがとうございます。びーだまさん
でも、動きません。
疑問点がいくつかあります。
> if ($ret == 1) {
>
> # HTTP 要求ヘッダー
>
> # POST メソッドで要求します。
> # ここを GET にすると、普通のブラウザみたいにすることも出来ますね。
> print SOCK "POST $file HTTP/1.0" . "\r\n";
perlのsocketがよくわからないのですが、connectしたソケットと、print SOCKのSOCKはどう結びついているのでしょうか?
> # ボディー部
> $flg = 0;
> while(<SOCK>){
> #*******************************************#
> # ここで、受信した内容についてあれこれする。#
> #*******************************************#
> }
あれこれって何をすればいいのでしょうか?
> # ソケットのバッファリングを停止
> select(SOCK);
> $| = 1;
> select(STDOUT);
このCGIはソケットクライアントですよね。selectの必要なしのような気がするのですが。
びーだま
[E-Mail]
2000/03/18(土) 20:56:56
ごめんなさい、既に動いていたもの(実は GET 用)から、切り出してちょこ
ちょこっとPOST用に変更を書いたので、動作確認していませんでした。
あまり、今時間がないところなので、まあ、POSTする方法の考え方は
わかっていただけたかとおもいますが、
SOCK は、このファイルハンドルを通じて、クライアント - サーバー
間の通信を行います。
わかりやすい言葉でなんていったら良いでしょう。
クライアントとサーバーの間に、通信用のパイプをつないで、
情報のやりとりはここを通じて行う。というイメージでしょうか。
要求も、応答も、この SOCK を使って行います。
> # ここで、受信した内容についてあれこれする。#
ところでは、この SOCK を通じて、サーバーからのレスポンスが
帰ってきます。例えば、POST で CGI をキックしたなら、HTTP
応答ヘッダーとそのCGI の出力した内容が、SOCK を通じてやって
きますから、
$_
の内容を、好きに処理すれば良いです。
> selectの必要なしのような気がするのですが。
実は、この辺の動作については私もどこかで習ったのをそのまま
鵜呑みにしているんですけど、実際どうなんでしょう。
しなくても動くのかな?と思いますが、しないと、直感的には、
サーバーに要求する際、バッファに貯まってしまって、実際に
サーバーには送信されず、処理が先に進まない気もします。
目に見えにくいので、実際に書いて確かめてみるのが一番でしょうか。
[上に]
[前に]
[次に]