ファイルの参照について

[上に] [前に] [次に]
dabo [E-Mail] 2000/02/21(月) 17:13:36
http://xxx.xxx.xxx/cgi-bin/でCGIを動かすとします。
http://yyy.yyy.yyy/sss/index.html(違うサーバーにあるファイル)のファイルを読み込みたいのですがうまくいきません。
ファイルの属性は755になってます。

どうしたら読み込めるようになるのでしょうか?
よろしくお願いします。

ジェリー [HomePage] 2000/02/21(月) 17:57:38
結論から言いますと不可能です。
それが出来たら立派なセキュリティーホールです(^^;;
SSIを使ったりインラインフレームを使ってみてはどうでしょうか?

dabo 2000/02/21(月) 18:16:18
i-GATE(http://www.i-greet.com/i-gate/)みたいのを
作ってみたかったんですけど、あれはどうやってるのでしょうか?

ちなみに作りたいのは、iモード用のHPをJフォン用に
変換するスクリプトを作りたいのです。

もしくは、そんなHPあったら教えてください。
ないと思ったので作ろうと思いました。
よろしくお願いします。

にしはじめ 2000/02/21(月) 18:39:31
open(FILE, "http://xxx.xxx.xxx")
のようなことはできません。
他サーバのファイルを持ってくるには、socketという機能を使います。
ここで解答を示すには大きすぎるテーマなので、ネットワーク/通信プログラミングの書籍を参考にして勉強するところから始めましょう。

ふじ 2000/02/21(月) 19:40:17
../199911/99110137.htm
過去の質問に同様のものが。

> open(FILE, "http://xxx.xxx.xxx")
PHPだとこんなことが出来ちゃいます。便利。
# 普通の ISP では使えないでしょうけど・・・

http://www.cityfujisawa.ne.jp/~louis/apps/phpfi/

ぺぱーど 2000/02/22(火) 00:57:19
>結論から言いますと不可能です。
あなたが以前した質問「open(IN, '***');の中に?を使うには?」
../200002/00020243.htm
の中で『別サーバにあるファイルの読み方』が紹介されていますが.
どうやらあなたは人からの回答を良く読んでいないようですね.

>それが出来たら立派なセキュリティーホールです(^^;;
別のサーバにあるファイルを読めなかったらブラウザでもアクセス出来ません.;-P
#知ったかぶりは見苦しいので辞めようね.

ジェリー 2000/02/22(火) 01:54:18
> 別のサーバにあるファイルを読めなかったらブラウザでもアクセス出来ません.;-P
> #知ったかぶりは見苦しいので辞めようね.

なに言ってるんですか(^^;
open関数では、他のサーバーのものは読めませんけど。

B-Cus 2000/02/22(火) 03:08:40
> 結論から言いますと不可能です。
> open関数では、他のサーバーのものは読めませんけど。
誰も「open 関数で」などと手段を限定してませんけど。

#  open(IN,"lynx -source http://foo.bar.com/index.html |");
#  open(IN,"wget -O /dev/stdout http://foo.bar.com/index.html |");
# これを「open関数で」と言っていいものかどうか。

ぺぱーど 2000/02/22(火) 03:53:03
>open関数では、他のサーバーのものは読めませんけど。
それじゃあ
>>SSIを使ったり
SSIを使えば別のサーバのファイルを読めるのですね?
これこそ「なに言ってるんですか」だけど.

>誰も「open 関数で」などと手段を限定してませんけど。
その通りですよね.


どうやらジェリー氏は人からの回答だけでなく質問内容も良く読んでいないようですね.

dabo 2000/02/22(火) 08:54:16
#  open(IN,"lynx -source http://foo.bar.com/index.html |");
#  open(IN,"wget -O /dev/stdout http://foo.bar.com/index.html |");

のどちらかで実行可能になるということでしょうか?

中立くん 2000/02/22(火) 09:21:55
煽っちゃダメダメ〜
daboさんの疑問を解決するのが最優先ですよ(^^)

>daboさん
とりあえず
http://www.tohoho-web.com/wwwperl2.htm#socket
にあるスクリプトを使えばファイルをGETすることができますよ。

dabo 2000/02/22(火) 09:33:20
ソケットってどこでもつかえるのでしょうか?
サーバのOSの種類とかperlのバージョンとかは
関係ないのでしょうか?

たまにperlのバージョンによっては動かないというのも
聞いたことがありましたので。
よろしくお願いします。

中立くん 2000/02/22(火) 09:55:08
http://www.tohoho-web.com/wwwperl2.htm#socket
はPerl4でも動くはずです。

Perl5だと"Socketモジュール"を使って、
Perl5.004以上だと"IO::Socketモジュール"を使って、
よりわかりやすいスクリプトを書くことが出来ます。

dabo 2000/02/22(火) 09:59:11
とりあえず、やってみます。
できなかった場合は、また、順をおって質問します。
ありがとうございました。

dabo 2000/02/22(火) 19:59:12
とりあえず、みてみたのですが、意味がわかりませんでした。

    $addr = (gethostbyname("www.xxx.zzz"))[4];
    $name = pack("S n a4 x8", 2, 80, $addr);
    socket(S, 2, 1, 0);
    connect(S, $name);
    binmode(S);
    select(S); $| = 1; select(stdout);
    print S "GET /index.html HTTP/1.0\r\n\r\n";←ここでページを取得しているのでしょうか?
    while (<S>) { print; }←ここで出力?
    close(S);

当たっているのでしょうか?
よろしくお願いします。

ぺぱーど 2000/02/23(水) 00:27:09
それであっています.(矢印の質問部分)
あってますが"\r\n\r\n"でなくて"\n\n"かと.

スラきち 2000/02/23(水) 00:43:35
> あってますが"\r\n\r\n"でなくて"\n\n"かと.
んー、違いますよ。RFC1945(HTTP/1.0)には改行はCRLF(\r\n)であることが定められています。でも、大体のサーバはLF(\n)だけのリクエストも受け付けてくれますけどね。

で、自分でちょっと改良してみました。perl5で動作確認済み。

$data = ""; # バッファをクリア
$addr = (gethostbyname("www"))[4]; # 名前からIPアドレスを取ってみる
$name = pack("S n a4 x8", 2, 80, $addr); # 取得対象のIPアドレスとポートを内部情報に変換
socket(S, 2, 1, 0); # とりあえずソケットを作る
connect(S, $name); # つないでみる
binmode(S); # バイナリモードにする
select(S); $| = 1; select(stdout); # バッファリングしないようにする
print S "GET /index.ht HTTP/1.0\r\n\r\n"; # リクエストを送ります
while (<S>) { $data .= $_; } # もらっています
close(S); # いらなくなったものを解放
die "invalid answer!" unless($data =~ /^HTTP\/[0-9]+\.[0-9]+ ([0-9]{3}) ([^\r\n]*)\r?\n/s); # ステータス番号は何だろうか
die "HTTP Error: Status $1($2)" if($1 != 200); # 200 は成功(OK)
$data =~ /(.*?\r?\n)\r?\n(.*)/s; # これでヘッダーと本体を分離
$header = $1; # 最初の方がヘッダー
$data = $2; # 後はデータ
print "Header = $header";
print "Data = $data";

これでも
・リダイレクトには反応できない
・サーバが死んでいる(反応がない)と自分も永遠に反応を待ち続けてしまう(これはselect使えば解決できるけど...)
という問題がありますが。

# そこまで考えると、open(IN,"wget -O /dev/stdout http://foo.bar.com/index.html |"); の方が楽かも...

とほほ 2000/02/23(水) 01:17:13
> どうやらあなたは人からの回答を良く読んでいないようですね.
いくら相手に非があろうと、トゲのある発言はやめてください。

> 結論から言いますと不可能です。
これは嘘ですね。
ジェリーさんも、不適切な回答が目立ちすぎるようです。
(それで、他の方がピリピリしておられるのではないかと思います。)
発言は極力正確にお願いします。

ぺぱーど 2000/02/23(水) 01:29:27
>んー、違いますよ。
おっと.失礼しました.(^^;
ActivePerl(Win32)(=改行は\nだけでCRLFになる)で作ってApche for WINで使っているとついつい.

>LF(\n)だけのリクエストも受け付けてくれますけどね。
ActivePerlで作った物をそのままApcheに持って行っても動いてしまうから余計に忘れるという.

dabo 2000/02/23(水) 09:19:56
スラきちの方法でYAHOOのトップページを読むことができました。
しかし、www.yahoo.co.jp/new/というページの読み込みを失敗しました。

なぜでしょうか?
/とか/~とかが入るとだめなのでしょうか?

よろしくお願いします。

ぺぱーど 2000/02/24(木) 01:46:02
$addr = (gethostbyname("www"))[4];
の"www"の所には"www.yahoo.co.jp"とサーバ名しか入れては駄目です.

"www.yahoo.co.jp/new/"を読みたい時は
print S "GET /index.htm HTTP/1.0\r\n\r\n";
の"/index.htm"の所を"/new/"とします.


汎用性を持たせるなら
*先頭に4行追加
$url = "http://www.yahoo.co.jp/new/";
$url =~ s/http:\/\///;
$host = substr($url, 0, index($url, "/"));
$dir = substr($url, index($url, "/"));

*以下の2行修正
$addr = (gethostbyname($host))[4];
print S "GET $dir HTTP/1.0\r\n\r\n";

とかして下さい.
#ホストとディレクトリ(ファイル)部分の分離は一例なので
#もっとスマートな方法もあるはず.

Selly 2000/02/24(木) 02:34:36
> print S "GET /index.ht HTTP/1.0\r\n\r\n"; # リクエストを送ります

バーチャルホストの場合を考えるとHostヘッダも発行した方がいいのでは?

print S "GET / HTTP/1.0\r\n"; # リクエストを送ります
print S "Host: www.yahoo.co.jp\r\n\r\n";
とか。

dabo 2000/02/24(木) 12:00:45
何度も質問しては、皆さんのお答えいただき本当に感謝しています。

いろいろなアドレスを入れて検査していたところ、FREEWEBの
HPが開けませんでした。
http://www9.freeweb.ne.jp/diary/accho/
ちなみにここを開こうとしたのですが、無理でした。
ファイル名を指定しても無理です。なぜでしょうか?
YAHOOの方は、うまく開けました。

方法としては、ぺぱーどさんの汎用せいのある方法+Sellyさんの
バーチャルホスト対応でやってみました。

よろしくお願いします。

みんこ 2000/02/24(木) 12:08:04
FREEWEBは内部ページの呼び出しは
トップページからでないものは全てはじく設定になってます。
これはCGIどうの、じゃなくて単にブラウザでブックマークしても同じです。
要確認。

dabo 2000/02/24(木) 12:38:05
そうですね。FREEWEBは。
忘れてました。

CGIのページも読み込むことはできるんですよね?
試してみたのですが、できませんでした。

前は、できたのですが。
よろしくおねがいします。

2000/02/24(木) 21:00:41
> FREEWEBは内部ページの呼び出しは
> トップページからでないものは全てはじく設定になってます。

そういった場合は内部ページのRefererヘッダを送ってやればいいです。

print S "GET / HTTP/1.0\r\n";
print S "Host: www9.freeweb.ne.jp\r\n";
print S "Referer: http://www9.freeweb.ne.jp/diary/accho/\r\n\r\n";

dabo 2000/02/25(金) 10:23:25
いろいろレスありがとうございます。

これは、最初のやつ。
print S "GET /index.html HTTP/1.0\r\n";

これは、バーチャルホストの場合
print S "GET / HTTP/1.0\r\n"; # リクエストを送ります
print S "Host: $host\r\n\r\n";

これは、サーバ名+ディレクトリ名の場合。
print S "GET $dir HTTP/1.0\r\n\r\n";
FREEWEB対応の場合。
print S "GET / HTTP/1.0\r\n";
print S "Host: $host";
print S "Referer: $url\r\n\r\n";

それぞれ対応できますが、
すべてに対応できるGETの方法はどのようにしたら
よいのでしょうか?

よろしくお願いします。

[上に] [前に] [次に]