Perl Script Laboratory

CGI・SSIの基礎の基礎

当サイトのコンテンツをhtmlソースごとそのままコピーして自分のサイトのコンテンツにしてしまう人がいます。そのような行為は当サイトの著作権を侵害する行為ですので絶対にしないでください。発見し次第断固とした措置を取ります。

CGIとは

CGI(Common Gateway Interface)とは、ユーザーがWeb上(ブラウザ、といった方が分かりやすいかもしれません)でプログラムを実行するための仕様のことです。CGIとはブラウザからプログラム呼び出して実行する仕組みのことであって、sh、csh、C、Perlなど、いろいろなプログラム言語を使うことができます。一般のプログラムと比較すると、CGIプログラムは入出力をブラウザを介して行うという特殊性があります。ここではCGIそのもののしくみではなく、CGIプログラムについて説明します。

CGIプログラムの特徴

プログラムファイルをサーバに置いて、サーバで実行させる

サーバサイド、という言葉を聞いたことがありますでしょうか? 例えばNIFTY-Serveを例にとると、会員各自のコンピュータからNIFTYのホストコンピュータにつないで、いろいろな操作をしますが、この時会員各自のコンピュータをクライアントといい、NIFTYのホストコンピュータをサーバといいます。CGIプログラムはサーバにプログラム本体(ファイル)を置いて、ブラウザからURLを指定して呼び出したときに実行されますので、サーバサイドプログラムということになります。

これに対して、JAVAスクリプトやJAVAアプレットは、プログラムはサーバに置いてありますが、これを自分のパソコンにダウンロードして、パソコン側で実行します。このようなプログラムをクライアントサイドプログラムといいます。一般に、サーバサイドプログラムは、サーバにかける負荷が大きく(実行させるのですから)、クライアントサイドプログラムはダウンロードするだけですので、サーバサイドプログラムに比べてサーバにかける負荷が少ないと言われています。

サーバで実行可能なさまざまな言語を使用できる

CGIプログラムはサーバで実行させるので、Perlはもちろん、自分のパソコンにCのコンパイラがなくても、サーバにあればC言語でプログラムを作ることもできます。シェル言語(sh)やruby、Pythonなどでももちろん作成できます。サーバかWindows系であれば、Visual Basicなども使うことができます。なお、「CGI」という名前の言語はありません。

CGIスクリプト

よく、CGIスクリプトという言葉を聞くと思いますが、スクリプトとは、プログラムの言語のうち、スクリプト(テキストファイル)を直接実行する言語(Perlやshなど)のプログラムのことをさします。C言語はソースファイルを実行ファイルにコンパイルするため、スクリプトとはいいません。

▲TOP


CGIプログラムの作成/編集に必要なツール

FTPソフト

Webページをすでに作成して公開している人であれば、FTPのためのツールはお持ちであろうと思います。Windows版、Mac版など、プラットフォームごとにフリーウエア、またはシェアウエアのさまざまなツールがありますので、各自気に入ったものを使ってください。
なお、CGIはプログラムであるため、このページの下で説明しているようにパーミッションの変更という作業が必要ですが、FTPソフトの中にはパーミッションの変更をFTPで可能にしているものもありますので、できればそういったツールを使った方が便利です。

テキストエディタ

Perlやshスクリプトの場合は、単にテキストエディタがあればプログラムを作成したり、公開されているスクリプトを編集したりすることが可能です。「メモ帳」でもOKですが、以下の機能を備えたものをおすすめします。
  - 行番号表示
  - 改行コード自動判別(CR+LF/CR/LF)
  - 日本語コードの自動判別(シフトJIS/EUC/JIS)
Windowsでは、秀丸エディタはgrep機能などもあり、大変便利です。

HTMLの知識

CGIプログラムは、出力をブラウザに対して行う以上、出力内容のほとんどはHTML形式です。そのため、プログラムの内容を知るためにHTMLの知識が欠かせません。また、フォームからの入力を受けてデータ処理するため、フォーム関連のタグ(form、input、select、textareaタグ) に精通している必要があります。

プログラム言語の知識

もちろん、プログラム言語の知識が必要です。フリーで公開されているものを直すだけでも必要になってきます。

▲TOP


CGIが使えるための条件

自分の加入しているプロバイダがCGIの使用を許可している。

こればかりはどうしようもない問題です。プロバイダから配布されたマニュアルを読むか、直接問い合わせてください。また、プロバイダによっては、.htaccessというファイルをホームディレクトリ(またはpublic_htmlディレクトリの中)に置くことでCGIを使えるようになる場合もあります。逆にいえば、CGIを使えるプロバイダに加入するといいでしょう。

CGIプログラムは、通常「.cgi」という拡張子をつけます。この拡張子をつけたプログラムをサーバにおいてブラウザから呼び出したときにファイルの内容が表示されてしまう場合は、CGIを実行する設定がされていない可能性があります。

CGIスクリプトを作るプログラム言語の実行環境があること。

例えば、PerlでCGI用のスクリプトを書いても、自分のプロバイダのサーバにPerlの本体がなければ、そのスクリプトはただのテキストファイルになってしまいます。また、Cのように実行するためにソースファイルをコンパイルしなければならないような言語の場合、サーバ上でコンパイルするためのプログラム(gccなど)がなければなりません。事前に調べる必要があります。

確認方法
% which perl(Enter)
または
% which gcc(Enter)
などとしてフルパスが表示されれば大丈夫です。
whichなどのシェルコマンドについてはunixの関連項目を参照してください。

セキュリティについての関心や知識を持っていること。

実行負荷について…共用レンタルサーバを借りてCGIを動かそうとしている場合は、自分が設置して実行させるプログラムがどのくらいサーバに負荷をかけるのか、通信回線を占有してしまうのかなどに配慮する必要があります。プロバイダによっては、そのような「重い」処理をするプログラムの設置及び実行を禁じているところもあります。事前に注意が必要です。

アルゴリズムについて…無限ループに陥ってしまうようなアルゴリズムを使うと、極端にいえば永久にそのプログラムは実行され続け、サーバが重くなり他のユーザーに迷惑をかける事になります。

データの汚染について…フォームからの入力をそのままサーバ上のコマンドに渡すプログラムは大変危険です。Perlでは、T(taint) スイッチを付けて実行することにより、引数指定(@ARGV)やフォームからの入力されたデータをそのまま外部コマンドに渡すことができなくなります。
熟練したプログラマであってもうっかりセキュリティホールを作ってしまうことがあります。開発する際は必ず -Tw スイッチを付けてください。

[例] #!/usr/bin/perl -Tw

参加型コンテンツの運用について…掲示板やチャットなど不特定多数の人が書き込みできるプログラムを作る場合には、悪意のあるイタズラに対して最大限の対策を施す必要があります。
IEの欠陥を悪用して、アクセスした人のハードディスクをフォーマットしてしまうようなファイルにリンクを貼ったりする事件が起きています。また、現在の法解釈上、例えば設置した掲示板に誰かが法に抵触するような記述またはイメージを投稿してプログラムの設置者が放置した場合は、プログラムの設置者の責任が問われることになります。
肉眼でのメンテナンスとともに、不必要に誰にでも書き込めるようにした掲示板やチャットを作らないように、十分注意しましょう。

▲TOP


CGIの設置方法

CGIスクリプトまたはソースファイルを記述する。

すでにでき上がっているフリーまたはシェアウエアのファイルがある場合はそれを使います。なお、プログラムの拡張子を.cgiに限定するなどの制限がある場合がありますので、プロバイダのマニュアルを読むか、各自のサーバ管理者に確認してください。

CGIファイルを置くディレクトリを決める。

CGIプログラムの実行を許可しているプロバイダであっても、ユーザーがセキュリティ上危険なプログラムを実行することを防ぐために、cgi-binディレクトリなど特定のディレクトリの中でだけ実行できるようサーバの管理者によって設定されていたりする場合があります。

CGIスクリプトまたはソースファイルをFTPする。

アップロードの際、CGI(ソース)ファイルの転送モードをASCII(テキスト)モードにしてください。バイナリモードで送ってしまうと、転送元のマシン(WindowsやMac)の改行コード(CR+LF/CR)のままとなり、Unix系の改行コード(LF)とのずれが生じてしまいます。

パーミッションの設定をする。

ApacheなどWebサーバがCGIプログラムを起動させるため、Webサーバがnobobyなど自分以外の権限で動いている場合は、その他 (others)の実行ビットを立てておく必要があります(755、705など)。一方、CGIWrapなど、ファイルのオーナーの権限で実行されるサーバの場合は、自分(owner)の実行ビットが立っていれば動作します(700など)。コマンドライン上で実行できて、ブラウザから呼び出すと実行できない場合は、パーミッションの設定を疑ってください。

パーミッションの変更は、コマンドプロンプトから

chmod 705 nantoka.cgi(Enter)

とします。

最近ではFTPソフトからパーミッションの変更をするのが一般的です。WindowsやMacのGUI環境で操作できるので、感覚的にわかりやすいでしょう。

▲TOP


SSIとは

SSI(Server Side Includes)とは、たいていのサーバが準拠しているNCSA httpdの持つ機能で、HTMLファイルの中に組み込みコマンドを書くことによって、ブラウザがそのファイルを要求したときに、サーバ側でコマンドを実行し、実行結果をその場所に挿入(Include)します。

アクセスカウンタを実現する方法としてよく使われ、ページの一部分を動的に実現したいときに適しています。

最近では、PHPのようなスクリプト言語もよく使われるようになりました。PHPもHTML中にプログラムを埋め込める点でSSIのしくみに似ています。

SSIのセキュリティについては、CGIの項に書いたことと同じで、フォーム等から入力した値をそのまま書き出すようなプログラムを書いてはいけません。 SSIの記述が含まれるファイルは.shtmlという拡張子をつけなければならないという制限があるのが一般的です。

SSIの記述方法

SSIの記述方法は非常に簡単で、通常のHTMLファイルの中に、

<!--#command option="…" -->

という表現を挿入するだけです。ここで指定されたコマンドがサーバ上で実行され、結果がこの位置に出力されます。例えば、日本の標準時刻を表示するには、HTMLソースファイルに

<!--#echo var="DATE_LOCAL" -->ですよ!

というように書いておくと、このファイルが読み出されたときには、

Saturday, 4-Jan-97 01:55:53 JSTですよ!

というように実行結果に置き替わります。
ここで出てくる DATE_LOCAL のような環境変数についてはhttpd環境変数を参照してください。

▲TOP


SSIで使われるコマンド

#config…出力形式の指定

  • errmsg="…"
    SSIの実行中にエラーが起こった場合にここで指定した文字列が出力されます。 ex))<!--#config errmsg="エラー">
  • timefmt="…"
    日付/時刻の出力フォーマットを指定します。パラメータは以下のとおりです。

    %c…日付と時刻(標準) Sat Jan 03 18:15:58 1997
    %x…日付(省略形) 04/26/95
    %X…時刻(省略形) 18:15:58
    %b…月(省略形) Jan
    %B…月(フルスペル) January
    %m…月(数字) 01
    %a…曜日(省略形) Sat
    %A…曜日(フルスペル) Saturday
    %d…日(数字) 03
    %y…西暦(2桁) 97
    %Y…西暦(4桁) 1997
    %H…時(24時制) 18
    %I…時(12時制) 6
    %M…分 15
    %S…秒 58
    %p…a.m.またはp.m. p.m.
    %Z…タイムゾーン JST

     ex))
    <!--#config timefmt="%Y年%m月%d日" -->
    <!--#echo var="DATE_LOCAL" --> 1997年01月03日
  • sizefmt="…"
    ファイルサイズの出力フォーマットを指定します。

    "bytes"…バイト単位で正確に出力します。
    "abbrev"…KBまたはMB単位で出力します。なお、この設定がデフォルトです。

#include…他のファイルを取り込んで出力

#includeは、そこで指定したファイルの内容を取り込んで出力するコマンドです。例えば、111.htmlの中に

<!--#include file="222.html" -->

と記述し、222.htmlの中身が

<p>このファイルは222.htmlですよ。</p>

という内容だったとすると、ブラウザから111.htmlを指定して表示させると、

このファイルは222.htmlですよ。

というようになるわけです。

  • file="ファイル名(相対パス)"
    取り込んで表示するファイルをカレントディレクトリを起点に、同じディレクトリか下のディレクトリにあるファイルに対して指定できます。
  • virtual="ファイル名(URL指定)"
    フルパス名でファイルが指定できます。例えば、わたくしのプロバイダのディレクトリで、
    http://www.jah.ne.jp/~akira67/222.html
    のファイルだったとすれば、
    <!--#include virtual="/~akira67/222.html" -->
    となります。

#echo…指定した変数などの値を出力

  • var="…"
    主に環境変数を表示させるために使います。冒頭の例を参照してください。環境変数名については、httpd環境変数を参照してください。 変数を参照してください。

#flastmod…最終更新日時の出力


#fsize…ファイルサイズの出力

この2つは指定したファイルの最終更新日時またはファイルサイズを表示させるために使います。オプションの指定方法は#includeと全く同じです。

#exec…コマンドを実行し、結果を出力

UNIXシェルコマンドあるいはサーバ上にある任意のプログラムを実行させるのに使います。通常プログラムを実行して標準出力に返す値(数値または文字列)を表示させる目的で使用します。

  • cmd="…"
    UNIXシェルコマンドを実行させるためのオプションです。注意しなければならないのは、自分で設置したプログラムの場合、呼び出すスクリプトがあるディレクトリのプログラムでなければフルパス名で指定しなければならないことです。
    ex)) <!--#exec cmd="echo count01.dat>
    ex)) <!--#exec cmd="/home1/ftp/akira67/public_html/cgi-bin/sample.pl">
  • cgi="…"
    CGIスクリプトを実行させるためのオプションです。URLと同様のパス指定をします。

▲TOP