CGIスクリプトの動作環境、環境変数、デコード方法について参考になると思われるスクリプトを作成してみました。詳細な説明は、スクリプトの中に書いてあるコメントを参照してください。wwwperl.cgiこのスクリプトを以下の場所に置いています。いろいろな方法で呼び出して、実行結果をみてください。(オフラインでは表示できません。)
- URLで呼び出す
- http://〜/〜/wwwperl.cgi
- URLで呼び出す(引数付き)
- http://〜/〜/wwwperl.cgi?aaa+bbb
- フォームからMETHOD=GETで呼び出す
- フォームからMETHOD=POSTで呼び出す
CGIスクリプトを記述する際に注意しなければならないことを、UNIXサーバーの場合、Windowsサーバーの場合に分けて説明します。(多くのプロバイダではUNIXサーバーを利用しています。たまにWindows NTサーバーもあるようです。)サーバーがCGIをサポートしていない(共通): セキュリティ確保のためCGIの使用を禁止していたり、CGIの設定を行っていなかったりするため、CGIを利用できない場合があります。
.htaccessファイルが必要?(UNIX): サーバが Apache などの場合、.htaccess というファイルの設定が必要な場合があります。プロバイダやサーバー管理者に問い合わせてください。
ローカルファイルを実行しようとしてる(共通): CGIスクリプトの動作チェックは必ず、http:// で始まるアドレスでアクセスしなくてはなりません。自分のパソコンでチェックしたい場合は、「Windows 95/98でCGIを動かそう」を参照してください。
perlのパス名はあっていない(UNIX): CGIスクリプトの1行目は、perlの絶対パス名(ディレクトリ上の位置)を正確に指定してください。絶対パス名がわからない場合は、プロバイダの説明を読んだり、サーバーの管理者に問い合わせてください。多くの場合、/usr/local/bin/perl や、/usr/bin/perl などに置かれています。
CGIスクリプトの場所が適切でない(共通): サーバーの設定によってはCGIスクリプトを置くディレクトリが制限されている場合があります。普段 HTMLファイルを置いているのとは別のサーバーに設置しなくてはならないプロバイダもあります。CGIスクリプトを置く場所がこのホームページで説明されている場所と合わない場合は、プロバイダの指示などに従って、適切にディレクトリを変更してください。
CGIスクリプトの拡張子が適切でない(共通): CGIスクリプトの拡張子が .cgi でなくてはならない場合があります。他にも .pl でなくてはならない場合もあります。これらも、サーバーの設定によって異なります。
perlがインストールされていない(Windows): Windows NTにはperlが標準では装備されていませんから、perl for Win32 や ActivePerl を入手してインストールする必要があります。また、MicrosoftのIISを用いる場合は、.cgi という拡張子に対して perl.exe が起動されるように、IISのヘルプを参照して設定を行う必要があります。(古いバージョンのIISではレジストリの追加が必要)
CGIスクリプトのパーミッションが誤っている(UNIX): サーバーがUNIXの場合は、CGIスクリプトファイルのパーミッションを755にしてください。また、CGIスクリプトが書込むデータファイルは、666 にしてください。一部のプロバイダでは、700 や 600 でなければならないところもあるそうです。
ユーザーの権限設定が誤っている(Windows): MicrosoftのIISでは、IUSER_MachineName というユーザーの権限でコマンドが実行されます。このユーザーがCGIスクリプトを実行する権限を持っているか確認してください。
ファイルの所有者が変(共通): 他のサーバーからデータファイルを移行させたときなど、ファイルの所有者が nobody でなくてはならないのに、自分自身の所有になっていて、パーミッションが 644 でもCGIがファイルに書き込めないことがあります。
CGIスクリプトの改行コードが変(共通): CGIスクリプトファイルの改行コードは、サーバーのOSタイプに適したものでなくてはなりません。
.htaccessの改行コードが変(共通): .htaccessを設置する場合は、.htaccessの改行コードもまた、サーバーのOSタイプにあわせてやる必要があります。
.htaccessの最後の行が改行されていない: .htaccessの最後の行が改行されていないと、その行は無視されてしまうようです。
CGIスクリプト内で使用するコマンドのパスが変(共通): スクリプト実行時、スクリプト内で使用するコマンドのパス(PATH)が通っていない場合があります。TELNETなどでログインした時のPATHと、CGIスクリプトが実行される時のPATHは異なるので注意してください。コマンドはなるべくフルパスで記述したほうが無難かもしれません。
最初の1行が変(UNIX): CGIスクリプトの最初の1行は「#!」で始めるようにしてください。CGIスクリプトは「#!」で始めなくてはなりません。「#!」の前に空白文字や空行があってもいけません。
ヘッダ行のあとの空行が無い(共通): Content-type: text/html などのCGIヘッダの後には必ず、1行以上の空行を出力してください。これを怠るとCGIスクリプトは正常に動作しません。
大文字、小文字の区別が誤っている(UNIX): UNIXというOSは通常、アルファベットの大文字と小文字を別の文字として扱いますので注意してください。たとえば、test1.cgi と TEST1.CGI はまったく別のファイルとして扱われます。
ブラウザのキャッシングに惑わされている(共通): ブラウザがCGIスクリプトの結果をキャッシングするために、スクリプトを書き換えても古い情報が表示されたりします。CGIスクリプト変更時には十分に注意して、再読み込みを欠かさないようにしましょう。
ヘッダにスペルミスがある(共通): 意外に多いのがこれ。Context-type: になっていたり、test/html や type/html になっていたり....もう一度確認してみましょう。
CGIスクリプトの出力漢字コードが変(共通): CGIスクリプトから出力する漢字コードはJISコードにするのが無難です。通常はブラウザが自動判断するのですが、Windowsで使用されているシフトJISと、UNIXで使用されているEUCの場合は誤判断してしまうことがあります。
ブラウザの漢字コード選択が変(共通): EUCのファイルを書き出しているのに、ブラウザの文字コード選択([表示]-[エンコード])がシフトJISのままになっていて、うまく表示できないケースがあるようです。
ファイルへの同時アクセスに注意(共通): CGIスクリプトは複数のブラウザ(ひとつのブラウザからでも)同時に起動されます。CGIスクリプトからファイルを更新する際は、ロックファイルの生成などにより排他制御を行う必要があります。
ブラウザの[画像表示]チェックがオフになっている(共通): CGIを<IMG>タグから呼び出す場合、Netscapeの場合[オプション]→[画像の自動読み込み]、Internet Explorerの場合[表示]→[オプション]→[情報]→[画像の表示]がオンになっていないと読み込まれません。
text/plain のわな(共通): Content-type: text/plain を使用した場合、Internet Explorer 3.0以降ではうまく動かないことがあります。 [表示]→[オプション]→[プログラム]→[ファイルタイプ]で、.cgiという拡張子のファイルにメモ帳などのプログラムを割り当てている場合、text/plain 形式の実行結果をダウンロードしてしまい、期待通りの動作をしないことがあります。
カレントディレクトリの差異(Win):Windows NT + IISの場合は、CGIスクリプトが動作する際のカレントディレクトリ(作業フォルダ)の場所が異なる場合があります。スクリプトの最初の方に、chdir("C:/HomePage/cgi-bin"); などの1行(C:/〜の部分にはCGIスクリプトを置いているフォルダを指定する)を追加することで回避できる場合があります。
もう一度スペルチェック(共通):すべて確認したのに、どうしても動かない・・・そういう時は、もう一度、すべてのスペルをチェックしてみましょう。大文字・小文字もあわせて見てください。l(小文字のエル)と I(大文字のアイ)と 1(数字の1)は間違えやすいので気を付けてください。
それでも、どうしても、動かなかったら・・・:それでも、どうしても、動かない時は、「CGIスクリプトをデバッグするには?」の方法でデバッグしてみてください。それでも動かなければ、質問メールを受け付けています。「とほほにメールを送る」の注意事項をよく読んで、ご質問ください。
また、これらの他にも、「私はこういう原因でつまずいた!!」というのがありましたら、追記したいと思いますのでお知らせ下さい。
通常のCGIスクリプトの出力はWWWサーバー経由でWWWブラウザに渡されますが、NPHスクリプト形式にすると、CGIスクリプトから直接WWWブラウザに渡されるため、WWWサーバーの負荷が軽くなり、速度も若干速くなります。CGIスクリプトをNPHスクリプトにするには次の2つの作業を行ってください。
次は、NPHスクリプトの例です。(nph-sample.cgi)
- CGIスクリプトを nph- で始まるファイル名にする。
- Content-type: を出力する前に、「HTTP/1.0 200 OK」を出力する。
- ヘッダ部の改行コードを \r\n にする。(\n のままでも動作するケースが多いが)
#!/usr/local/bin/perl binmode(STDOUT); print "HTTP/1.0 200 OK\r\n"; print "Content-type: text/html\r\n"; print "\r\n"; print "<HTML>\n"; print "<HEAD>\n"; print "<TITLE>NPHスクリプトのテスト</TITLE>\n"; print "</HEAD>\n"; print "<BODY>\n"; print "これは、NPHスクリプトのテストです。\n"; print "</BODY>\n"; print "</HTML>\n";
SSIやCGIは便利さの代償としてセキュリティ上非常に危険なものです。以下の文章はセキュリティを強化するために必要な情報ですが、反面、未防御のシステムに対してアタックをかけるための情報にもなってしまいます。この場で記載すべきかどうか悩んだのですが、このホームページの読者を信用して公開することにしました。index.htmlを設置する: CGIスクリプトを置くディレクトリには index.html を置いておきましょう。index.html が存在しない場合、cgi-bin ディレクトリをブラウザでみるとCGIスクリプトの一覧が見えてしまいます。ファイル名からセキュリティホールのあるスクリプトを見つけてアタックされる可能性が高くなります。
見られるとまずいファイルはpublic_htmlの外に: パスワードファイルなど、見られるとまずいファイルは、public_htmlの外など、通常の閲覧者が見ることのできないディレクトリに置きましょう。(それでも、同じサーバーにログインできる人や、他の人のCGIのセキュリティホールのために、見られてしまうことはあります。)
evalの危険性: perlはよく分からないのでCGIスクリプトをシェルで記述しよう・・・と思った時など、CGIスクリプトのパラメータを解釈するためによく、UNIX のシェルの eval を利用しますが、これは大変危険です。 もし、変数名NAMEの値として「値;危険なコマンド」を指定されると・・・
grepの危険性: 「grep $KEY file」というコードも危険です。 もし、KEYの値としてバッククォーテーション( ` )で囲まれた「`危険なコマンド`」を指定されると・・・
SSIの危険性: チャットや伝言板など利用者の書き込んだメッセージを表示するシステムではSSIに注意してください。 もし、「<!--#exec cmd="危険なコマンド"-->」を書き込まれると・・・
パスワード漏洩の危険性: 人様のパスワードを扱う場合はとにかく厳重に扱ってください。 多くの人は同じパスワードを使いまわします。 あなたのサービスが不法使用されるだけでなく、同じパスワードを使いまわしていた他の有料サービスも不法使用される恐れがあります。 あなたのCGIスクリプトは完璧でも、同じサーバー上の他の人の不備で情報が漏れる可能性もあります。 パスワード情報ファイルに password.txt などといった安直な名前はつけないようにしましょう。
Windows NTのIIS(Internet Information Server)でもperlスクリプトによるCGIを動作させることは可能です。以下の手順に従ってください。(1)まず、下記のサイトからPerl for Win32、もしくは ActivePerl を入手してインストールしてください。
http://www.ActiveState.com/(2)最近のバージョンのIISではIISの設定画面の「構成(アプリケーションのマッピング)」で、.cgi という拡張子についての設定を追加するそうです。ちょっと古いバージョンのIISでは、レジストリエディタ([スタート]-[ファイル名を指定して実行]からREGEDT32.EXEで起動)で、以下の値を設定する必要があります。(C:\Perl5\bin の個所は、perlをインストールした場所に応じて適切に変更してください。)
キー HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ W3SVC \ Parameters \ Script Map 名前 .cgi 値の型 REG_SZ(文字列) 値 C:\Perl5\bin\perl.exe %s %s (3)IISの設定で、CGIを設置するディレクトリ(フォルダ)に対して、[実行]というアクセス権が設定されていることを確認した後、IISを再起動してください。
(4)IISでのCGIは「IUSER_マシン名」というユーザーの権限で実行されます。CGIスクリプトの実行権、CGIスクリプトがアクセスするファイルへのアクセス権などを確認してください。
(5)IISでは、CGIスクリプト実行時のディレクトリ(フォルダ)が、CGIスクリプトを設置したフォルダと異なる場合があります。CGIの最初の方で、chdir("CGIスクリプトを設置したフォルダ名"); のように、実行時フォルダ(カレントディレクトリ)を移動させてやる必要がある場合があります。
(6)上記のレジストリの %s を忘れると、xxx.cgi?arg1+arg2 で指定した引数がCGIスクリプトに渡されないことがあります。
(7)UNIXのCGIで設定していた、755などのファイルのパーミッションは、Windowsでは設定する必要はありません。
→ WindowsでCGIを動かすには? に移動しました。
CGIを実行すると、http://.../.../xxx.cgi?aaa&bbb&ccc のように、CGIへの引数が表示されてしまうことがあります。この?以降の文字を表示させないようにするには、以下の手段があります。(1)POSTを用いる: <FORM METHOD=GET ACTION="..."> の代わりに、<FORM METHOD=POST ACTION="...">を用いると、?以降の文字がURLではなく標準入出力で渡されるため、表示されなくなります。ただし、CGI側もPOSTに対応する必要があります。
(2)Location:で飛ばしてやる CGIで処理を行った後、Content-type:ヘッダの代わりに Location: ヘッダで一度別のHTMLやCGIに飛ばしてやると、表示されなくなります。