この節には、PHP、Perl、および C を使って記述されたサンプル FastCGI アプリケーションが含まれています。
<?php $dir = "/tmp/"; // ある既知のディレクトリを開き、続いてその内容を読み取ります if (is_dir($dir)) { if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { echo "filename: $file : filetype: " . filetype($dir . $file) . "\n"; } closedir($dh); } } ?>
この例に対する obj.conf の一部を次に示します。
<Object name="default"> NameTrans fn="assign-name" from="/fcgi/*" name="responder.fcgi" </Object> <Object name="responder.fcgi"> Service fn="responder-fastcgi" app-path="/foo/fastcgi-enabled-php-installation/bin/php" bind-path="localhost:3431" min-procs=3 </Object>
#!/usr/bin/perl use FCGI; while (FCGI::accept >= 0) { if( $ENV{'HTTP_AUTHORIZATION'} ) { # この値をさらに復号化すれば、実際のユーザー名とパスワードが得られるので、 # 何らかのユーザー検証を実行できます。このプログラムでは、この環境パラメータ # の存在チェックしか行っておらず、その値を実際に処理しているわけではありません print( "Status: 200\r\n" ); print( "\r\n" ); } else { print( "Status: 401\r\n" ); print( "WWW-Authenticate: basic realm=\"foo\"\r\n" ); print( "\r\n" ); } }
この例に対する obj.conf の一部を次に示します。
<Object name="responder.fcgi"> AuthTrans fn="auth-fastcgi" app-path="/fastcgi/apps/auth/SimpleAuth.pl" bind-path="localhost:3432" Service fn="responder-fastcgi" app-path="/foo/fastcgi-enabled-php-installation/bin/php" bind-path="localhost:3433" app-env="PHP_FCGI_CHILDREN=8" min-procs=1 </Object>
http://localhost/fcgi/php/ListDir.php への要求が初めて発生すると、ブラウザによって認証ダイアログボックスが表示されます。ユーザー名とパスワードの入力が完了すると、「/tmp」ディレクトリの内容が一覧表示されます。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcgi_stdio.h> void main(void) { size_t PageSize = 1024 * 3; char *page; FCGX_Stream *in, *out, *err; FCGX_ParamArray envp; int count=0; page = (char *)malloc(PageSize); if (page == NULL) { printf("Content-type: text/x-server-parsed-html\r\n"); printf("<title>malloc failure</title>"); printf("<h1>Cannot allocate memory to run filter. exiting</h1>"); printf("\r\n\r\n"); exit(2); } while(FCGI_Accept() >= 0) { char *tmp; char *execcgi; char *dataLenStr = NULL; int numchars = 0; int stdinDataSize = 0; int filterDataLen = 0; int dataToBeRead = 0; int x = 0; int loopCount = 0; count++; dataLenStr = getenv("FCGI_DATA_LENGTH"); if(dataLenStr) filterDataLen = atoi(dataLenStr); /* stdin のクリア */ while (EOF != getc(stdin)) { stdinDataSize++; } dataToBeRead = filterDataLen; FCGI_StartFilterData(); tmp = page; /** fread や fwrite が我々のポインタを動かす場合にそなえて **/ // 応答を開始します printf("Content-type: text/plain\r\n"); printf("\r\n"); /** send a new line at the beginning **/ printf("<title>SIMPLE FILTER</title>"); printf(<h1>This page was Filtered by SimpleFilter FastCGI filter</h1>"); printf("file size=%d<br>", filterDatalen); printf("stdin size=%d<br>, stdinDataSize); while(dataToBeRead > 0 ) { x = 0; page = tmp; if(dataToBeRead > PageSize) x = PageSize; else x = dataToBeRead; numchars = fread((void *)(page), 1, x, stdin); if( numchars == 0 ) continue; /** この時点で、データは page ポインタに格納されています。したがって、そのデータをサーバーに送り返す前に、そのデータに対して必要な操作をすべて行ってください。この例では、データ操作は一切行っていません。各ループの末尾でフィルタデータの読み取り回数と読み取り済み合計バイト数を出力しているだけです。**/ dataToBeRead -= numchars; loopCount++; printf("loop count = %d ... so far read %d bytes <br>", loopCount, (filterDatalen - dataToBeRead)); } printf("\r\n\r\n"); /** 転送終了時に改行を送信します **/ fflush(stdout); page = tmp; /** ページポインタを復元します **/ memset(page,NULL,numchars); } free(page); }
この例に対する obj.conf の設定例を次に示します。
この FastCGI アプリケーションが、Web Server が稼働しているのと同じマシン上で利用可能になっている場合は、次のようにします。
<Object name=<"filter.fcgi"> Service fn="filter-fastcgi" app-path="/fastcgi/apps/filter/SimpleFilter.exe" bind-path="localhost:3434" app-env="LD_LIBRARY_PATH=/fastcgi/fcgi-2.4/libfcgi/.libs" </Object>
このアプリケーションがリモートマシン上で実行されている場合には、obj.conf ファイル内に次のコード行を含める必要があります。
<Object name="filter.fcgi"> Service fn="filter-fastcgi" bind-path="<remote-host>:<remote-port>" </Object>
Web Server インスタンスのドキュメントルートディレクトリの下にある fcgi ディレクトリに格納されたサイズ「26868」バイトの「FilterThisFile」が、フィルタリング対象のファイルである場合、「http://localhost/fcgi/filter/FilterThisFile」への要求によって次の出力が生成されます。
This page was Filtered by SimpleFilter FastCGI filter
file size = 26868 |
stdin size = 0 |
loop count = 1... so far read 3072 bytes |
loop count = 2... so far read 6144 bytes |
loop count = 3... so far read 9216 bytes |
loop count = 4... so far read 12288 bytes |
loop count = 5... so far read 15360 bytes |
loop count = 6... so far read 18432 bytes |
loop count = 7... so far read 21504 bytes |
loop count = 8... so far read 24576 bytes |
loop count = 9... so far read 26868 bytes |