(since 1998/5)(更新 2003/12/07)

TNO:CGIのトラブル・ガイド

情報系/IT系の広告を掲載しています。(広告一覧)
私自身が実際に経験した、 CGI(Perl)作成の際のトラブルです。
今後も増えるでしょう。(^^)?polipoli
©Copyright 1998-2003 小野智章(小野情報設計)
無断転載を禁止します。

Perlスクリプト(プログラム)を自分で書こうという人を、 読者として想定しています。 HTMLやJavaScriptに付いては、ページ最下段のリンクで。
尚、サーバやブラウザによって仕様が異なる場合が有ります。
そろそろ、このページもCGIとSSIに分割かなぁ。 構成も変えてみたいし。
CGIが、TikiのWebサーバからCGI専用サーバへ移行しています。 従って、現状を意味する部分は、実際の現状と一致していない場合があります。

  1. require
    Perlの「require」文でライブラリ等を設定する場合、
    そのライブラリの最後に真値を返すための「1;」が必要です。
    参考書やオンライン・マニュアルにも載ってないので、 実例を調べるまで全く気が付きませんでした。
  2. charset
    文字コードの設定に「charset」を使用します。
    HTMLではメタで、CGIでも最初の標準出力行に付加出来ます。 SSI用のCGIでは、設定しないと、 CGI部分のみの文字コードが変ってしまうことがあります。
    ところがCGIでページ全体を表示させ様とする場合、 「更新」「再読み込み」させないと表示しなくなってしまいました。
  3. Cookie
    Cookieには、path設定があります。
    CGIプログラムは、専用ディレクトリに入れます。 そこでCookieを設定すると、 path設定はCGIプログラム専用ディレクトリになります。
    ところがSSIを使用した場合、
    (例:<!--#exec cgi="cgi-bin/〜.cgi"-->)
    path設定は SSIを使用したHTMLファイルのパスに なってしまいます。
    お陰で、Cookieが見つからずに困ってしまいました。
  4. Cookie2
    Cookieには、有効期限があります。
    同じ名前で同じパスのCookieを設定すると、 有効期限が後になるCookieが残る様です。 でも、後から設定した期限の早いCookieが、 一時的に見えることもある様です。
    対策は、有効期限を後になる様にすることです。
  5. Cookie3
    同じ名前でパスの違うCookieを設定すると、 両方見えて区別出来ません。
    もちろん、許可されたパスに限られますが。
  6. Path[Aタグ]
    CGIで表示したページのリンクPathが正常に動いていない。
    「<A HREF="../〜.html">」が
    「<A HREF="〜.html">」扱いされる。
    原因不明。取りあえず絶対Path
    「<A HREF="./../〜.html">」かも?
    (ぶっきらぼうなのは、「原因不明」のため。)
  7. 漢字コード
    Perlプログラムをサーバ上で実行すると、 シフトJISの漢字コードが文字化けすることがあります。 「表示」の「表」等の様に、漢字コードの2バイト目が、 半角「¥」と同じコードになる場合です。 シングル・クォート「’」中では、起こらないですが。
    半角「¥」発見方法 ==>
    小道具:「漢字→%」変換
    本来はEUCを使うべきですが、 その「表」等の文字の次に半角「¥」を入れて、 「表\示」等としておけば取りあえずOKです。
    半角「¥」が潰れるため、文字化けが起きます。 もう一個「¥」を加えておけば、 2個で1個の「¥」の代わりになるので文字化けを抑制出来る訳です。
  8. each
    Perlのeach関数による検索を中断して、 同じ連想配列を次にeachで検索すると、 前の検索の続きになってしまいます。
    オンライン・マニュアルにも載っていますが、 見落としていました。
  9. 文字列変数
    Perlで文字列を変数に入れてサブルーチンの引数にした場合、 いつのまにか空文字列になってしまっていることがあります。
    原因不明です。
    取りあえず、引数を「変数名.''」(<=ダブル・クォートじゃないぞ!)としてやればOKです。
  10. HTML名
    1つのCGIが複数のHTMLから呼び出される場合、 HTMLからSSIでCGIを呼び出した際に、 呼び出したHTMLの名称がほしいことがあります。
    $ENV{'REQUEST_URI'}」で可能です。
    ただし、サーバやブラウザによって仕様が異なる場合があります。
  11. Cookie4
    CGIからの出力のヘッダで、Cookieを設定することが出来ます。 しかし、SSIで呼び足されるCGIでは、 Cookieを設定することが出来ませんでした。
    取りあえず、 SSIで「<IMG SRC="〜/〜.cgi">」を出力し、 その<IMG>タグのCGIでCookieヘッダを出力すればOKです。
    尚、そのCGIで出力する画像データが正しいものでないと、 ブラウザが再読み込みしようとするので、 Cookieを2回送ってしまいます。
  12. CGI用ディレクトリ(フォルダ)
    「user-cgi」などが、プロバイダに指定されます。
    セキュリティを考えてわざと違う名前にしておいたら、 いつの間にかFAQページに変更が必要というメッセージが。
    大移動が必要になってしまいました。 しかも、古いディレクトリも、しばらくは残す必要がありました。
  13. Path2[SSI−include]
    SSIのincludeで指定しようとするPathが、 うまく動いてくれませんでした。
    「<!--include file="../〜.txt"-->」のファイルが、 無いものとして扱われます。 「"./../〜.txt"」も駄目!
    取りあえず、 SSIを使ったディレクトリ内にもそのファイルをコピー して回避しました。
    ……と思っていましたが、 「<!--include virtual="../〜.txt"-->」の様です。
    絶対URLとは、「http://」から書けるという意味ではない様です。 「..」は無視されるかと思いましたが、違う様です。
  14. ファイル名
    ファイル名の規則は、実行環境によって異なります。
    CGI(Perl)プログラムをサーバにアップする前に、 当方のパソコン(Windows95)上で 動作試験をしています。 が、この動作環境はMS−DOSモードで、 ファイル名の規則もMS−DOSになってしまいます。 UNIXやWindows95のつもりで長いファイル名を使うと、 ファイル名の後ろが切られてしまい、 ファイルが読めなかったりします。
    以前も同じ間違いをしたのですが、 つい忘れてしまい、 しばらく原因が判らず混乱してしまいました。 UNIXのことも考えると、 CGIでアクセスするファイルは 半角英小文字で 「8文字以内+拡張子3文字以内」に して置くのが良い様です。
    また、MS−DOSモードで作成したファイルのファイル名を、 Windows95で表示すると 小文字表示されることがあります。 しかし、実際のファイル名は大文字になっていて、 UNIXへ転送すると、 大文字と小文字を区別されて アクセス出来ない事態が発生します。
  15. アクセス・カウンタ
    「<IMG>」タグでCGIを呼び出して アクセス・カウンタをカウント・アップする場合、 カウントされないアクセスがある様です。
    ロボットや巡回ソフトからのアクセスで、 「<IMG>」タグを無視する様になっているためと思われます。
    対策は、SSIでCGIを呼び出してカウント・アップする手でしょうか。 それとも、メタ・タグのリフレッシュを使い、 ページを丸ごと表示させるCGIへジャンプして、 そこでカウントするしか無いでしょうか。
    ちなみにTNOページでは、 「<IMG>」タグとSSIを両方併用していました。 又、一時、SSIエミュレータでカウントしていました。
  16. アクセス・カウンタ2
    ページ表示の度にアクセス・カウンタをカウント・アップすると、 連続したアクセスを多重にカウントしてしまいます。 が、それで良いという仕様にするのが最も簡単です。
    防止には、期日無しの保存されないクッキーを発行するか、 「$ENV{'REMOTE_ADDR'}」等と アクセスした日時をファイルに記録しておく手でしょう。
    ちなみにTNOページでは、両方併用していました。 が、保存されないクッキーの設定でも、 数日前のクッキーを残しているケースもある様です。
    現在はIPアドレス毎の最終アクセスを記録して、 30分以内はカウントしないようにしています。
  17. chmod
    理解が間違っていた。 「オーナー」のみ書き込み可能の設定のファイルに、 CGIで書き込みが出来る。
    「オーナー」は、アクセスした人(アカウント)ではなく、 書き込んだプログラムのこと。
    FTPでは、CGIで書き込んだファイルは上書き/chmod出来ず、 削除しか出来なくなります。 一旦削除した上で、新たに書込みし直しします。
  18. SSI停止
    1998/8/10の20時頃、プロバイダが突然SSI機能をオフしてしまった。
    殆どのページでSSIを使用している上に、 SSI無しでは重要なページが表示されなくなってしまった。
    上記についてプロバイダに問い合わせて、 SSIは使用出来ないとのメール。 これに対応するには、 全ぺージの構成、仕様などを全面的に見直して修正する必要があるが、 時間が無い。 仕方が無いので、暫定でSSIエミュレータを組み込んで対応。
  19. SSI停止-2
    プロバイダからの連絡無しに、 いつの間にかインクルードや更新日付の機能が復活していた。 要は、execを禁止したかった様だ。
    SSIエミュレータで対応していたが、 エミュレータ無しでも殆どのページは表示出来る様になった。 が、既にエミュレータ対応にページを変更しているので、 更に直すのは躊躇。 表示も出来ているし、 エミュレータ無しでは実現出来ない機能も付加している。 今後再び、インクルードや更新日付の機能が停止するかもしれないし。
    と思っていたら、停止してしまいました。 SSIエミュレータも停止して、対応におおわらわでした。
  20. FORM
    次の様にFORMタグのACTIONで直接パラメタを指定しようとしたら、 パラメタに「?」がくっ付いて「B=j?」となってしまった。
    <FORM ACTION="bbs_answer.cgi?B=j">
    当たり前ではあるが。
  21. パラメタの受け渡し
    "〜.cgi/P=xxx"でパラメタ受け渡しをすると、 相対URLがおかしくなる。 "yyy.cgi"を"〜.cgi/yyy.cgi"と解釈してしまう。 (ブラウザにもよるのかもしれないが。)
    "〜.cgi?P=xxx"ならOK。
  22. パターン・マッチ
    パソコン上のPerlで、 「/[\200-\376]/」などの形でパターン・マッチをしようとした。 が、「[]」の中では、 シフトJIS漢字を1文字としてマッチしようとしている様な気がする。
    サーバでは確認していないが、 動作確認のためにはパソコンで動かないと困る。 漢字変換は「%16進」の状態でするしかないか。
  23. 2000年問題
    インターネット上/CGI上でも、2000年問題が発生します。
    1998/9月現在、 TNOの利用しているCGIプロバイダのサーバでは、 Perlのlocaltimeの年は2桁になっていました。 2000/1月現在、システムの年は100となっています。 が、いつ4桁化するか判ったものではありません。
    ということで、 1998年から、年が2桁でも4桁でも、 1900年からの差でも良いようにプログラムしてありました。 皆さんの対応はどうでしょう。
    一般的なシステムの、外部から送られて来るデータについても、 両方に対応出来るようにした方が良いですね。
  24. ページ内参照
    CGIで表示した頁でも、次の様な「#」を付けたページ内参照が可能。
    http://ww3.tiki.ne.jp/~tno2/user-cgi/ssi.cgi?html=trouble@trouble2.htm#Yen
    なぜか出来ないと思い込んでいました。
  25. *.ps
    SSIのinclude機能で、 拡張子「.ps」のファイルがinclude出来ない。
    拡張子を変えると可能。 原因不明だが、この拡張子に何らかの特殊用途があるのか?
  26. CGIの移行
    プロバイダが、CGI実行環境を外部の別のプロバイダへ委託。 CGIを新しいサーバへ移行しなければならないが、 移行先のCGIの殆どの実行で、原因不明のエラー。
    FTPで、複数のCGIファイルをまとめて転送すると、 その実行時にエラーになる模様。 個別転送でも、なることがある様だか。 再度転送し直すと、何事も無かったかの様に、正常動作。
    ASCIIとBinaryの転送モードが、拡張子によって自動設定されていなかった模様。
  27. 容量
    CGI移行先で、容量オーバーになった。
    移行元では10MBだったため問題が無かったが、 移行先は1MB。 普通なら十分の容量で、 ファイル・サイズの合計なら十分に制限内。
    しかし、 問題発行の小さいファイルが300×2ぐらいあり、 移行の暫定処置で更に+300。 ファイル記録が1KBぐらい(cluster)単位で行われているため、 それら合計で既に約900KB。 CGI自体のファイルを加えれば、……
    取りあえず、暫定の+300を削除して移行処置を完了し、 その後ゆっくりと対策を取りました。
  28. パターン・マッチング
    新しいCGIサーバ環境のパターン・マッチングで、「@」が使えない。
    旧環境で動いていた次のパターンが、新環境で動かない。
    /\e(%24[@B]|%28[BJI])/
    仕方が無いので、次の様に変更。
    /\e(%24[\@B]|%28[BJI])/」
    原因は、Perl4からPerl5への移行でした。
  29. SSI機能も停止
    CGIの旧サーバ停止に伴い、 「exec」以外のSSI機能も停止した様です。
    これまでのプロバイダの対応状況から見て、 復活するのか、しないのか、 判断がつかない。
  30. 半角「@」が半角「”」で囲った文字列中などでも、使えない。
    半角「’」で囲った文字列中や半角「¥@」なら、OK。
  31. CGI環境の移行1
    CGI作成環境をWindowsのまま、 インターネット接続環境をWindowsからLinuxへ移行した所、 FTPで転送したCGIプログラムが動作しなくなってしまいました。 結論から言うと、 CGIの改行コードが、Windows形式(CR+LF)では駄目で、 UNIX形式(LF)でないと動作しないためでした。 拡張子「.pl」のライブラリは、Windows形式でも大丈夫だったため、 気付くのが遅れました。
    Windows環境からのFTP転送では 改行コードを変換する様に設定していました。 そのファイルをそのままLinuxへ送って、 そこから改行コードを変換せずにFTP転送したためでした。
    対策は、Linux下でnkfコマンドで変換し、 その後の修正はeMacsで行うことにしました。
  32. CGI環境の移行2
    CGIで読込ませるファイルをWindowsで作成する必要があり、 前述と同様、そのままLinuxからFTP転送していました。 当然、改行コードが異なり、CGIの動作に支障が出ました。
    このファイルはLinuxでは作成出ず、一々変換するのも大変なので、 どちらの改行コードでも対応出来る様にしました。 具体的には、各行の終わりのLFを削除していた所を、 LF削除の後でCRも削除するようにしました。

質問・ご意見等、お待ちしております。 質問については、判る範囲で出来るだけ答えて行きたいと思います。
小野智章(小野情報設計) 
Mail連絡先

JavaScriptのトラブル・ガイド
ホーム・ページのトラブル・ガイド
T掲示板
トップ・ページへ

©Copyright 1998-2003 小野智章(小野情報設計)
無断転載を禁止します。