CGI (EXE) の動作の仕組み
CGI とは?
- Common Gateway Interface (CGI)
- Web サーバからデータを受け取り、応答をWeb サーバ経由でクライアントに返すプログラムあるいはプログラムとのインターフェイス。
CGI は上記に示すような Web サーバのインターフェイスであるのですが、 IIS では CGI というと、EXE プログラムによる Web アプリケーションということになります。
典型的な例では C 言語で作る EXE プログラムが CGI の例になります。
環境変数
CGI では環境変数からデータを取得します。CGI として起動されたプログラムでは、環境変数から次の名前のデータが取得可能です。 ASP.NET や PHP などに慣れている人は、その名前からある程度内容が推測できます。
CGI 1.1 で決められている基本的な環境変数は次の通りです。
- SERVER_SOFTWARE
- SERVER_NAME
- GATEWAY_INTERFACE
- SERVER_PROTOCOL
- SERVER_PORT
- REQUEST_METHOD
- PATH_INFO
- PATH_TRANSLATED
- SCRIPT_NAME
- QUERY_STRING
- REMOTE_HOST
- REMOTE_ADDR
- AUTH_TYPE
- REMOTE_USER
- REMOTE_IDENT
- CONTENT_TYPE
- CONTENT_LENGTH
- HTTP_ACCEPT
- HTTP_USER_AGENT
この他に IIS では次のページにあるような各種環境変数に値がセットされます。
IIS Server Variables
環境変数の取得
- getenv または GetEnvironmentVariable を使用して取得する
- 設定されていない環境変数は IIS5.1 以前では NULL が返されたが、IIS6 以降では "" が返る。
CGI だからといって環境変数の取得に特別なことがあるわけではありません。 C 関数 getenv 関数あるいは Windows API である GetEnvironmentVariable 関数を使用します。
また、仕様というよりはただの実験結果ですが、値のセットされていない CGI 環境変数を取得しようとすると、 特定の環境変数が設定されていない場合、IIS 5.1 以前では NULL が返されたが、IIS 6 以降では "" が返ります。
サンプルコード
環境変数を表示する CGI プログラムは次のようになります。
#include <windows.h> #include <stdio.h> #include <fcntl.h> #include <io.h> int main ( int argc, char* argv[] ) { char* pContentType = NULL; char *lpvEnv, *lpszVariable; _setmode( _fileno( stdin ), _O_BINARY ); _setmode( _fileno( stdout ), _O_BINARY ); // HTTP HEADER printf ("Content-Type: text/html\r\n"); printf ("\r\n"); // HTML HEADER printf ("<html>"); printf ("<head>"); printf ("<body>"); // EXE NAME AND PARAMETERS printf ("<h1>%s</h1>", getenv("SCRIPT_NAME")); lpvEnv = GetEnvironmentStrings(); if (!lpvEnv) { printf ("GetEnvironmentStrings failed (%d)", GetLastError()); return 1; } printf ("<table border='1'>"); for (lpszVariable = (char*) lpvEnv; *lpszVariable; lpszVariable++) { printf ("<tr><td>"); while (*lpszVariable) { putchar( *lpszVariable++ ); } printf ("\r\n"); } FreeEnvironmentStrings(lpvEnv); printf ("</table>"); printf ("</body></html>"); return 0; }
CGI の起動とデータの流れ
- CreateProcessAsUser API でCGIプロセスを起動する
- 第8引数に環境変数ブロックを設定する
- STARTUPINFO の標準入出力にてパイプを設定する
IIS がこのような仕掛けで CGI を起動するため、CGI 側では単に標準入出力 (stdin, stdout) に対して読み書きすればよいのです。