• ベストアンサー

CGIの中で異なるContent-typeのファイルを・・・。

CGIでの処理で、今 http://xxxx.com/ok.cgi?id=123&pass=abc&page=index.html でindex.html が表示されているとします。 それで、このindex.htmlから別の拡張子のファイルへリンクさせ、ファイルをダウンロードできるようにしたいと思っています。lzh ならURLはこん感じになります。 http://xxxx.com/ok.cgi?id=123&pass=abc&page=sample.lzh  しかし ok.cgi の最後で print "Content-type: text/html\n"; exit; を指定しているのでリンク先へ行ってもindex.htmlは表示されますが、リンク先のファイルは動きません。 どうすればダウンロード出来るようになるでしょうか? なるべくこのok.cgi の外に出したくないのです。  また、この中で、リンク先が隠れるphpを入れたいと考えましたが、phpも同様に機能しません。これもどのようにすればよろしいでしょうか?  どなたかよろしくお願い致します。

  • Perl
  • 回答数4
  • ありがとう数4

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

  • ベストアンサー
  • taporu
  • ベストアンサー率44% (46/104)
回答No.4

#2です >if($in{'page'} eq "") { $in{'page'} = "index"; } if($in{'page'} eq "") { $in{'page'} = "index.html"; } >open(IN,"./tmp/$tsite/$in{'page'}.html"); open(IN,"./tmp/$tsite/$in{'page'}")||&ErrorNotFile; >print "Content-type: text/html\n\n$buffer\n"; if($in{'page'} =~ /^(.*?)\.html$/){ print "Content-type: text/html\n\n$buffer\n";exit; }elsif($in{'page'} =~ /^(.*?)\.lzh$/){ print "application/x-lzh-compressed\n\n$buffer"; exit; }else{ print "Content-type: text/html\n\n不正なファイルが要求されました。"; } #以下追加 sub ErrorNotFile { print "Content-type: text/html\n\nファイルが存在しません"; exit; } のように変えてください。

senyou2000
質問者

お礼

ありがとうございます。  ダメです....(T^T;)  例えば、改造なしで、最初からlzh を対象とするとして、直接 sample.lzh へ向かうように。  if($in{'p'} eq "") { $in{'p'} = "sample"; }  open(IN,"./item/$tsite/$in{'p'}.lzh");   while(<IN>){$buffer.=$_;}  close(IN);   #省略#  print "application/x-lzh-compressed\n\n$buffer\n"; のみにしておいてもファイルが出てきません。 ダウンロード時に現れるダイアログのファイル名には、 IEではただ「ok」、 オペラでは「ok.cgi」になっており、 「sample.cgi」が出ないのです。    いったいどういう事なのか・・・・。  この場合すぐダイアログが現れるので ブラウザURLの最後に ~sample.lzh 部分がありません。  http://xxxx.com/ok.cgi?id=123&pass=abc  の状態です。  そしてプログラムをいじらないままで、まずindex.htmlへ向かい、そこからsample.lzhへリンクすると ブラウザのURLはきちんと http://xxxx.com/ok.cgi?id=123&pass=abc&page=sample.lzh となっていますが、この場合には今度はダイアログさえ出てきません。  もうなにがなんだか....。

senyou2000
質問者

補足

最初はそのままコピペしたのでlzhのところ Content-type: が抜けていたので表示されなかったようです。その後いろいろやってみましたが、このままだと使えませんね(笑 zip の場合 Content-type: application/zip 及び application/octet-stream で検証。 それぞれダイアログに出てきたファイル名と成否です。 opera: ok.zip (一応ダウンロード出来、ファイルも正常) firefox: ok.cgi IE6: ダイアログなしでいきなりダウンロードでいきなり解凍。一応ファイルは正常たが、探さないとどこに収まったか分からない。どこにあるか分からない為ファイル名は不明。逆に不明だからすぐにはどこにあるか分からない。 lzh の場合 Content-type: application/octet-stream 及び application/x-lzh-compressed で検証。 opera: ok.cgi (ダウンロードしても開かない) fierfox: ok.cgi (ダウンロードしても開かない) IE6: ダイアログなしでいきなりダウンロード。一応ダウンロード出来ていたが、探さないとどこに収まったか分からない。ファイル名はok.lzh php の場合 opera: 表示されない。 Firefox: 表示されない。 IE6: 表示されない。 phpだけでも正常に機能してくれたら、リンク先も見えないのでcgiの外に出すのですが...(泣

その他の回答 (3)

回答No.3

エラーの内容がわからないので、何とも言えないですが、ファイルの読み 取り権限とか、パスの問題のような気がします。パスの場合はフルパスで 指定するとどうでしょうか? else { print $q->header( -type => 'application/octet-stream', -attachment => $page ); # tmpにファイルがあるとして、 my $full_path = '/tmp/' . $page; open my $fh, '<', $full_path or croak "$page: $!"; binmode $fh; my $buffer = ''; while ( read $fh, $buffer, 1024 ) { print $buffer; } close $fh or croak "$page: $!"; } あるいは、次のようにして問題を切り分けするのも手です。次のようにすれば、'Hello CGI'という内容のテキストファイルがダウンロードできます。 else { print $q->header( -type => 'application/octet-stream', -attachment => $page ); print "Hello CGI\n"; } >print $q->end_html; はprint を付けると 1 と言う文字が表示 これは、 >print $q->header( -charset => 'UTF-8' ); のラストを , に変更するに >はしましたが これが原因だと思います。 一つのprint文で済ませたいときは、 print $q->header( -charset => 'UTF-8' ), $q->start_html( -lang => 'ja', -title => ' T I T L E ' ). $q->end_html; として下さい。一つのprint文で済ますのが、一般的かもしれませんね。

senyou2000
質問者

お礼

再度ご教授ありがとうございます。 エラーですが、Internal Server Error と出るだけで、詳しい内容は私も分からないのです。  No,2様のものと平行してこちらも勉強させて頂いています。 実は cgi pm というものをしらなかったので、今さらですが、調べながら触っています。  こちらももう少しテストしていきたいと思います。 ちなみに現状のプログラムはNo,2様の回答欄をご覧下さい。  

senyou2000
質問者

補足

補足覧をお借りしてお礼申し上げます。  別途ある処理の仕方を思いつき、うまくいきました。  お二人様ありがとうございました。

  • taporu
  • ベストアンサー率44% (46/104)
回答No.2

このようなものでは? if($IN{'page'} =~ /^(.*?)\.html$/){ print "Content-type: text/html\n\n"; }elsif($IN{'page'} =~ /^(.*?)\.lzh$/){ print "application/x-lzh-compressed\n\n"; }else{ print "Content-type: text/html\n\n不正なファイルが要求されました。"; } のように、正規表現で分ける。

senyou2000
質問者

お礼

ありがとうございます。 現在いじっているCGIのログイン部ですが、以下のようになっています。 古くに作って頂いたCGIで、それに手をくわえたいと思っていました(作った人は今連絡が取れない)。 昨日からお教えいただいたものを入れようとしましたが、わたしの知識不足で、挫折ぎみです。 お手数ですが、以下の場合どのように手を加えれば宜しいでしょうか? #ok.cgi  ログイン部分 ####################### sub login { if($in{'page'} eq "") { $in{'page'} = "index"; } # tmp以下に入れるとしています。 open(IN,"./tmp/$tsite/$in{'page'}.html"); while(<IN>){$buffer.=$_;} close(IN); $buffer =~ s/<!--id-->/$in{'id'}/ig; $buffer =~ s/<!--passwd-->/$in{'pass'}/ig; # 諸事情から ~.ok.cgi?id=<!--id-->&pass=<!--passwad-->&page=index となっています。 # 別に ?id=$id&pass=$pass でいいと思いますが・・・。それはそれとして・・・。  print "Content-type: text/html\n\n$buffer\n"; exit; } ######################### よろしければ再度ご教授下さい。

回答No.1

GETパラメータで処理を分ければいいんじゃないかなあ #!/usr/bin/perl -T use warnings; use strict; use utf8; use CGI; use CGI::Carp qw(fatalsToBrowser); use CGI::Pretty; my $q = CGI->new(); my $id = $q->param("id"); my $pass = $q->param("pass"); my $page = $q->param("page"); if ( $page eq 'index.html' ) { print $q->header( -charset => 'UTF-8' ); print $q->start_html( -lang => 'ja', -title => ' T I T L E ' ); print $q->end_html; } else { print $q->header( -type => 'application/octet-stream', -attachment => $page ); open my $fh, '<', $page or croak "$page: $!"; binmode $fh; my $buffer = ''; while ( read $fh, $buffer, 1024 ) { print $buffer; } close $fh or croak "$page: $!"; }

senyou2000
質問者

お礼

ありがとうございます。  どうもうまくいきません。 print $q->header( -charset => 'UTF-8' ); のラストを , に変更するにはしましたが、その後 else{ } を入れた段階でエラーになってしまいます。  ところで print $q->end_html; はprint を付けると 1 と言う文字が表示されてしまうので、purint は要らないと思って良いのですよね?  うまくいかないのは何が原因でしょうか?

関連するQ&A

  • ページの識別をクエリでやらせる意味は?

    ネット上で、以下のようなアドレスをもったサイトを見かけることがあります。 http://www.abc.com/?page_id=company http://www.abc.com/?page_id=product http://www.abc.com/?page_id=support http://www.abc.com/以降のファイル名が省略されていますが、おそらくindex.cgiだかindex.phpだかのサーバーサイドプログラムが置いてあって動作しているのだと思います。クエリpage_idの値を取得し、それによってプログラムで表示するページの内容を変えているのだと思いますが、なぜわざわざこのような方法と使っているのでしょうか?それぞれcompany.htmlまたはcompany/index.htmlのようにhtmlファイルを用意する方が簡単だと思うのですが。phpなどのプログラムはSEOに弱く、SEOを気にするなら文書データであるhtmlデータの方が良いと聞いたこともあります。

  • CGIで表示されるページ(hoge.cgi)に

    CGIで表示されるページ(hoge.cgi)に <meta http-equiv="Refresh" content="5;URL=www.abc.com"> とメタタグを記述し、5秒後に指定URL(abc.com)に飛ぶようにしているのですが、 この方法ですとジャンプ先(abc.com)ではリンク元(hoge.cgi)が特定できません。 ジャンプ先でリンク元URLを特定できるようにしたいのですが、何か方法はありませんでしょうか?

    • ベストアンサー
    • CGI
  • CGI文字コードの設定

     CGIにて、日本語の文字列を送信して、次のページでそれを表示する ということを試みています。例えば、 "page A"からリンクで"page B"に飛ぶとします。 --- page A (HTML)--- <a href="http://abc.dom/index.cgi?query=$string">Link</a> そのとき、"page B"の題名を"page A"のリンクの中から取り出すとします。 --- page B (HTML)--- <h1>$string</h1>  そこで、$stringに日本語を入れて送信したいのですが、 送信する前に、エンコードして、 --- page A (CGI)--- $string = "日本語"; # 例えば $string =~ s/(\W)/sprintf("%%%02X", unpack("C", $1))/eg; print "<a href=\"abc.dom?query=$string\">Link</a>"; 受信した後、デコードして、 --- page B (CGI)--- $string =~ tr/+/ /; $string =~ s/%([0-9a-fA-F][0-9a-fA-F])/pack("C", hex($1))/eg; print "<h1>$string</h1>"; のようにしているのですが、うまく表示してくれません。  カーソルを"Link"に合わせると、ステータスバーには http://abc.dom/index.cgi?query=□u□{□e... このような文字化け?したものが表示されます。(...は続くという意味です。) しかし、アドレスバーには http://abc.dom/index.cgi?query=%93%FA%96%7B%8C%EA と表示され、エンコードがなされていることが分かります。  実際に、クリックしてリンク先を見てみると、 $BF|K\8l (B というようなわけの分からない文字列が表示されます。 ブラウザ表示は『日本語(Shift-JIS)』になっていますが、 色々と設定を変更しても同様にうまく表示されません。  エンコードやデコードをよく理解していないのかもしれませんが、 どなたか私のやっている中のバグをご指摘して頂けないでしょうか。

    • 締切済み
    • CGI
  • htmlでCGIを作動させたい

    PC用とモバイル用のサイトを作成しています。 http://www.abc.com/ にアクセスすれば自動で振り分けするよう index.cgiというCGIスクリプトを作成しました。 それをindex.html内に組み込んで自動でCGIを呼び出すことは可能でしょうか? 何故わざわざindex.htmlをつくるかというと、METAタグで検索エンジンに引っかかるようにする為です。 <!--#exec cmd="index.cgi"--> を入れてみましたが、振り分け先リンクが表示されるだけで自動では飛んでくれませんでした。 以下、index.htmlのソースです。 <html> <head> <title>ああああ</title> <meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta name="description" content="ああああ"> </head> <!--#exec cmd="index.cgi"--> </html> 拙い文章&初歩的な質問で申し訳御座いません。 何卒よろしく御願い致します。

    • ベストアンサー
    • CGI
  • POSTとGETについて

    POSTとGETについて2点質問が御座います。 PHPは最近手を付け始めましたので、初心者です。 (1)PHPでPOSTとGET両方使うことは出来ますでしょう   か? 内容:PHPファイルからCGIに値を引きつきたいのですが、テキストエリアのフォーム(POST)とCGIのリンク先に"hogehoge.php?id=xxxx"とGETのxxxxとPOSTのテキストエリアに記載した内容を2つ引き継ぎたいのですが、GETの方の値がCGIで反映されていません。 POSTとGETの両方引きつぎたいときはどのようにすれば良いでしょうか? (2)また(1)とは、別の話ですが、GETだけで2つの情報を引き継ぐことは可能でしょうか? "hogehoge.php?id=xxxx,?id2=yyyy"のようなイメージでxxxxとyyyyの両方を渡したいと思ってます。 どうかご教授宜しくお願い致します。

    • ベストアンサー
    • PHP
  • フリーのCGIをさがしています。

    以下リンク先のような、商品一覧と個数、送り先住所が1つになっているような形のフォームを作りたいと思っています。 http://aeg-network.com/cgiscript/form_comp/index.html 同じような形のフォームが作成できる、フリーのCGIがあればダウンロードして使用したいです。 まだCGIはあまり詳しくないので、なるべく簡単なものを希望します。 心当たりのある方、教えてください!

    • ベストアンサー
    • CGI
  • PHPで変数を暗号化する方法

    PHPで、変数を暗号化したいのですが、 いい方法が有ればぜひ教えて頂きたいです。 たとえば http://abc.com/index.php?id=123 というのを http://abc.com/index.php?id=3934987d98bcd8 のようにして、idをわからないようにしたいのですが・・ よろしくお願いします。

    • ベストアンサー
    • PHP
  • socketを使って外部のファイルを呼び込む

    $Host = 'abc.hogehoge.co.jp'; $Page = "/test_order.cgi?pass=1234&id=1234' $Addr = (gethostbyname($Host))[4]; $Name = pack("S n a4 x8", 2, 443, $Addr); socket(S, 2, 1, 0); connect(S, $Name); binmode(S); select(S); $| = 1; select(stdout); print S "GET $Page HTTP/1.0\r\n\r\n"; $Data = ''; while (<S>){ $Data = $_; } close(S); print"$Data"; 現在ある決済システムを組み込もうとしております。 上のように外部ホストのアクセスしてパスワードやID、その他あるのですがそれで接続していてもどうにも$Dataに出力されません。 print S "GET $Page HTTP/1.0\r\n\r\n"; とありますが外部ファイルはhtmlファイルではありません。たんなるテキスト文字が出力されるはずです。 直接ブラウザに https://abc.hogehoge.co.jp/test_order.cgi?pass=1234&id=1234' とたたくとテキストが出力されます。 なにかまちがっているのでしょうか? 恐れ入りますがご教授お願いします

    • ベストアンサー
    • CGI
  • CGIの改造お願いします

    CYANDY CGI(ttp://www.candy-cgi.com/)で配布されている ランキング/Ranking Type1についての質問です。 配布ページ ttp://www.candy-cgi.com/perl/Ranking_Type1.html http://www.xx.com/xx.php?mode=xx&xx_id=123456 上記のような【xx_id=12456の数字のみが変化するURL】を対象に、 Ranking Type1をDLし設置したのですが、 どのidページからアクセスしても 【http://www.xx.com/xx.php?mode=xx】という 同一のアクセスになってしまいます。 これを、【http://www.xx.net/xx.php?mode=xx&xx_id=123456】として カウントするようには出来ないでしょうか? 改造OKとのことでしたので、こちらに投稿させて頂きました。 宜しくお願い致します。

  • URLにCGIのファイル名を出さない方法

    同じCGIを使ってサービスしているサイトで、URLにCGIのファイル名を含むサイトと 含まないサイトがあります。例えば bbs.cgi というCGIだとすると、  (A) http://foo.com/bbs.cgi/page01  (B) http://bar.com/page01 というサイトがあります。この違いはどこから来るのでしょうか? 同じCGIを入手してインストールしましたが、現状(A)の状態です。 (B)のようにしたいと思っていますが、やり方が分かりません。 よろしくお願いいたします。

    • ベストアンサー
    • HTML

専門家に質問してみよう