CGI(Common Gateway Interface)

未分類

CGI(Common Gateway Interface)とは?

WEBサーバの機能の主体は、あらかじめ用意された情報をクライアントの要求に応じて送り返すことである。
そのため、WEBサーバ単体では情報を動的に生成してクライアントに送信する仕組みを作ることができなかった。
そこで、WEBサーバプログラムから他のプログラムを呼び出し、その処理結果をクライアントに送信する方法が考案された。
それを実現するためのサーバプログラムと外部プログラムとの連携法の取り決めがCGIである。

CGI は、典型的には以下のような動作を期待される。

・CGIプログラムはウェブサーバがクライアントからのリクエストに応じて起動する。
・CGIプログラムへの情報の入力は、環境変数、標準入力によって行われる。
・プログラムが標準出力に出力したデータは、ウェブサーバを経由してクライアントに送られる。

このデータは正当なHTTPヘッダで始まらなければならない。
ただし、いくつかの特別なヘッダフィールドは「サーバディレクティブ」として解釈され、ウェブサーバの挙動(ステータスコードなど)に影響を与える。
これ以外の全てのヘッダフィールドはそのままクライアントに送信される。

CGIへの入力

CGIにデータを入力する方法は、2種類の方法があります。

1.GETメソッド

HTMLフォームの入力内容を RequestURLの後ろに付与して連携します。

例)www.shintaro.info/~shintaro/cgi-bin/example.cgi?name1=value1&name2=value2

RequestURLの後ろに付与された文字列は、 WEBサーバにより環境変数 QUERY_STRINGに格納されます。
CGIプログラム側は、環境変数 QUERY_STRINGの値を参照することで入力データを受け取れます。

GETメソッドは、HTTP/0.9が規定された当時、 WEBサーバにデータ送信する唯一の手段でした。
しかし、255文字分のデータしか格納できないという制限があるため、現在では、後発の POSTメソッドを利用することが主流になっています。
QUERY_STRINGの値は、コマンドのオプションのように手軽に値を変更できるため、用途によっては便利なメソッドです。

2.POSTメソッド

HTMLフォームの入力内容が RequestBodyとして連携されます。
RequestBodyのデータ長は、 WEBサーバの環境変数 CONTENT_LENGTHに設定されます。
RequestBodyのデータは、 WEBサーバの標準入力から取り出せます。
CGIプログラム側は、環境変数 CONTENT_LENGTHに設定されたデータ長の分、標準入力のデータを読み込むことで、入力されたデータを受け取れます。

GETメソッドのようにデータの内容を手軽に変更できませんが、 Curlコマンドを使えば、入力値を手軽に変更することも可能です。

入力パース機能 (JavaのRequestParameterクラスのようなもの ) を作ってみよう。

1.入力データ(name=value&name=value…)をデータ構造体に変換する関数を作成する。

データ構造体の定義は、次の通りとする。

typedef struct _TD_NameValue {
char* psName;
char* psValue;
} TD_NameValue;

構造体の実体は、オブジェクト内 (RequestParameter.o)のみ参照可能とする。 (後述のアクセサのみ参照可能とする )
関数プロトタイプ(インターフェース定義)は、次の通りとする。

allocRequestParameter(void);

2.データ構造体から、データ項目名をキーに、データ項目値を返す関数を作成する。

関数プロトタイプ(インターフェース定義)は、次の通りとする。

char* getRequestParameterValue(char* psKey);

3.データ構造体から、データ項目名をキーに、データ項目値(複数)を返す関数を作成する。(チェックボックスなどの値を取得するための関数です)

関数プロトタイプ(インターフェース定義)は、次の通りとする。

char** getRequestParameterValues(char* psKey);

出力テンプレート機能 (JavaのVelocityのような出力ライブラリ ) を作ってみよう。

下記の通り、設計&実装してみよう。

1.CGI実行ディレクトリに配置されたテンプレートHTMLを1行ずつ読み込む。

<html><body>
<p>$1$さんのIDは$2$です。</p>
</body></html>

2.読み込んだ1行にデータを埋め込むタグがあった場合、データを埋め込んで出力する。

<p>$1$さんのIDは$2$です。</p> → <p>〇〇さんのIDは〇〇です。</p>

3.タグと出力データのマッピングは、CGIプログラムのヘッダーファイルに定義する。
(外部ファイルで定義しても良いです。JavaでXML定義に進化したので…)

typedef struct _TD_TemplateMappings {
char *psTag;
char *psValue;
} TD_TemplateMappings;
TD_TemplateMappings[] tdTemplateMappings = {{“1”, “hoge”}, {“2”, “huga”}, {NULL, NULL}}

NameValue構造体(入力用とは別に出力用を定義)の生成ロジック(モデル)、出力テンプレート(VIEW)、データとテンプレートのマッピング(コントローラ)、の構成にすることで、MVCモデルの設計が可能になります。

コメント

タイトルとURLをコピーしました