3. 最初のCGIプログラム
この章では、C言語で最小構成のCGIプログラムを作り、ブラウザに文字列を表示します。
ここで確認したいことは、CGIプログラムが「Webサーバから実行され、標準出力にHTTPレスポンスを書き出すプログラム」だという点です。
この章で学ぶこと
- C言語で最小のCGIプログラムを書く
- HTTPレスポンスヘッダを自分で出力する
- CGIプログラムをコンパイルして実行可能ファイルにする
- ApacheのCGI実行ディレクトリに配置する
- 表示できない場合の基本的な確認点を知る
CGIプログラムの要件
CGIプログラムは、Webサーバから外部プログラムとして呼び出されます。C言語で書く場合は、ソースコードをコンパイルし、実行可能なバイナリとして配置します。
一般的な要件は次のとおりです。
- WebサーバがCGI実行を許可しているディレクトリに置く
- 実行権限が付いている
- HTTPレスポンスヘッダを標準出力に書き出す
- ヘッダと本文の間に空行を入れる
配置場所は環境によって異なりますが、Debian / Ubuntu系のApacheでは /usr/lib/cgi-bin/ が使われることがあります。
Cで書く最小のCGIプログラム
以下は、ブラウザに Hello, CGI と表示する最小構成のCGIプログラムです。
#include <stdio.h>
int main(void) {
printf("Content-Type: text/html; charset=UTF-8\r\n");
printf("\r\n");
printf("<!DOCTYPE html>\n");
printf("<html lang=\"ja\">\n");
printf("<head><meta charset=\"UTF-8\"><title>Hello CGI</title></head>\n");
printf("<body>\n");
printf("<h1>Hello, CGI</h1>\n");
printf("</body>\n");
printf("</html>\n");
return 0;
}
ポイントは、HTML本文の前に Content-Type ヘッダを出力していることです。
Content-Type: text/html; charset=UTF-8
HTTPレスポンスでは、ヘッダと本文の間に空行が必要です。上のCコードでは、2回目の printf("\r\n"); がその空行にあたります。
ビルドと配置
ソースコードを hello.c として保存し、次のようにコンパイルします。
gcc hello.c -o hello.cgi
生成した hello.cgi に実行権限を付けます。
chmod 755 hello.cgi
ApacheのCGI実行ディレクトリに配置します。
sudo cp hello.cgi /usr/lib/cgi-bin/
ブラウザまたは curl で確認します。
curl -i http://localhost/cgi-bin/hello.cgi
ブラウザで確認する場合は、次のURLにアクセスします。
http://localhost/cgi-bin/hello.cgi
うまく表示されないときは
ブラウザに 500 Internal Server Error が表示される場合は、次の点を確認します。
- CGI実行ディレクトリでCGIが許可されているか
hello.cgiに実行権限があるか- Webサーバの実行ユーザーがファイルを読めるか
Content-Typeヘッダを出力しているか- ヘッダと本文の間に空行があるか
- プログラムが異常終了していないか
Apacheのエラーログも確認します。
sudo tail -f /var/log/apache2/error.log
実行ファイルのオーナーとパーミッション
CGIプログラムは、ApacheなどのWebサーバから実行されます。そのため、ファイルの所有者が自分のユーザーであっても、Webサーバのプロセスが実行できる権限になっている必要があります。
学習用の環境では、まず次のように確認するとよいでしょう。
ls -l /usr/lib/cgi-bin/hello.cgi
例として、次のように実行権限が付いていれば、少なくともファイル権限の問題は切り分けやすくなります。
-rwxr-xr-x 1 root root 16000 Jun 1 12:00 hello.cgi
補足:ユーザディレクトリでCGIを動かす場合
Apacheの設定によっては、システム全体のCGIディレクトリではなく、ユーザーごとの ~/public_html 以下でCGIを実行できます。
URLは次のような形になります。
http://localhost/~username/cgi-bin/hello.cgi
この構成を使うには、mod_userdir の有効化、ExecCGI の許可、ディレクトリ権限の調整が必要です。初心者向けの最初の実験では /usr/lib/cgi-bin/ のような標準的なCGIディレクトリを使い、必要になったらAppendixでUserDir構成を確認してください。
次章では、フォームから送られた入力値をCGIプログラムがどのように受け取るかを見ていきます。