Sun Java System Web Server 7.0 Update 3 管理员指南

附录 B FastCGI 插件

简介

FastCGI 是对现有 CGI(Common Gateway Interface,公共网关接口)的增强,CGI 是一种连接外部应用程序与 Web Server 的标准。与 CGI 一样,FastCGI 应用程序在单独、隔离的进程中运行。以下是使用 FastCGI 的一些优点:

通过使用 FastCGI 插件,Web Server 能够以可伸缩的方式安全地使用流行的第三方动态内容生成技术(如 Perl 和 Python)。

有关 FastCGI 的更多信息,请参阅 http://www.fastcgi.com/devkit/doc/fcgi-spec.html 中的规范。

插件函数 (SAF)

FastCGI 插件提供以下服务器应用程序函数 (Server Application Function, SAF):

以下各节介绍了 FastCGI SAF 的各种参数和“错误原因”字符串:

auth-fastcgi

auth-fastcgi 是修补程序检查函数。此函数用于将请求转发到“授权者”FastCGI 应用程序。如果授权成功,则发送返回码 200。否则,将“授权者”FastCGI 应用程序的响应发送回至用户代理。

可以在 http://www.fastcgi.com/devkit/doc/fcgi-spec.html#S6 中找到有关 FastCGI 角色的更多信息。

以下位置提供了 auth-fastcgi SAF 接受的参数: FastCGI SAF 参数

以下 obj.conf 代码示例说明了 auth-fastcgi 的用法:

PathCheck fn="auth-fastcgi" app-path="/usr/bin/perl" app-args="/fastcgi/apps/auth/SimpleAuth.pl" bind-path="localhost:3432"

responder-fastcgi

responder-fastcgi 是服务函数。此函数用于将请求转发到充当“响应者”的 FastCGI 应用程序。“响应者”应用程序的响应将被发送到用户代理。http://www.fastcgi.com/devkit/doc/fcgi-spec.html#S6 中提供了有关 FastCGI 角色的更多信息。

以下位置提供了 responder-fastcgi SAF 接受的参数列表: FastCGI SAF 参数

以下 obj.conf 代码示例说明了 responder-fastcgi 的用法:

Service fn="responder-fastcgi" app-path="/fastcgi-enabled-php-installation/bin/php" bind-path="localhost:3433" app-env="PHP_FCGI_CHILDREN=8" app-env="PHP_FCGI_MAX_REQUEST=500"

filter-fastcgi

filter-fastcgi 是服务函数。此函数用于将请求转发到“过滤器”类型的 FastCGI 应用程序。“过滤器”应用程序接收与 HTTP 请求关联的信息,还接收存储在服务器上的文件中的数据。然后,“过滤器”应用程序生成“已过滤”版本的数据流作为响应。该响应将被发送到用户代理。http://www.fastcgi.com/devkit/doc/fcgi-spec.html#S6 中提供了有关 FastCGI 角色的更多信息。

以下位置提供了 filter-fastcgi SAF 接受的参数列表: FastCGI SAF 参数

以下 obj.conf 代码示例说明了 filter-fastcgi 的用法:

Service fn="filter-fastcgi" app-path="/fastcgi/apps/filter/SimpleFilter" bind-path="localhost:3434" app-env="LD_LIBRARY_PATH=/fastcgi/fcgi-2.4/libfcgi/.libs" min-procs=2

error-fastcgi

error-fastcgi 是错误函数。error-fastcgi SAF 处理特定于 FastCGI 插件的错误。但是,此函数不处理 HTTP 错误。发生错误时,可以将 FastCGI 插件配置为显示特定的页面或将请求重定向至特定的 URL。

以下位置提供了 error-fastcgi SAF 接受的参数列表: FastCGI SAF 参数

以下 obj.conf 代码片段说明了 error-fastcgi 的用法:

Error fn="error-fastcgi" error-reason="Invalid Parameters" error-url="http://www.foo.com/errorPage.html"

有关 error-fastcgi 参数的信息,请参见FastCGI SAF 参数

FastCGI SAF 参数

FastCGI 插件 SAF "auth-fastcgi"、" responder-fastcgi" 和 "filter-fastcgi" 全都接受下列参数,除非另外显式说明:

请注意,chrootusergroupnicechdirrlimit_asrlimit_corerlimit_nofile 参数仅适用于 UNIX 平台。在 Windows 平台上,这些参数都将被忽略。

error-fastcgi 服务器应用程序函数 (Server Application Function, SAF) 接受以下参数:

error-fastcgi SAF 错误原因字符串

本节提供了所有有效“错误原因”字符串及其说明:

在 Web Server 上配置 FastCGI 插件

FastCGI 插件与 Web Server 7.0 捆绑在一起。可以使用以下某种方法在 Web Server 上配置 FastCGI 插件:

在 Web Server 上手动配置 FastCGI 插件

插件将安装在以下位置:

32 位 FastCGI 插件二进制文件安装在 <install_dir>/plugins/fastcgi 目录中。

64 位 Solaris SPARC FastCGI 插件二进制文件安装在 <install_dir>/lib/plugins/fastcgi/64 目录中。

将安装以下 FastCGI 二进制文件:

libfastcgi.so(适用于 Solaris/Linux)

fastcgi.dll(适用于 Windows)

Fastcgistub.exe(适用于 Windows)

libfastcgi.sl(适用于 HP-UX)

Fastcgistub(可执行文件)

可以使用位于 <instance-dir>/config 目录中的 Web Server 配置文件来配置 FastCGI 插件。要配置 FastCGI 插件,请执行以下步骤:

修改 magnus.conf

使用 "load-modules" 初始化函数加载 FastCGI 插件共享库。

Init fn=flex-init access="access" format.access="%Ses->client.ip%
- %Req->vars.auth-user% [%SYSDATE%] \"%Req->reqpb.clf-request%\"
%Req->srvhdrs.clf-status% %Req->srvhdrs.content-length%"

Init fn="load-modules" shlib="libJava EEplugin.so" shlib_flags="(global|now)"

Init fn="load-modules" shlib="libfastcgi.so" shlib_flags="(global|now)"

修改 MIME 类型(可选)

编辑 mime.types 文件以指定 MIME 映射。修改 MIME 类型映射为可选步骤。

例如,

#--Sun Microsystems Inc. MIME Information

# Do not delete the above line. It is used to identify the file type.

#

# Copyright 2006 Sun Microsystems, Inc. All rights reserved.

# Use is subject to license terms.

#


type=application/octet-stream exts=bin

type=application/astound exts=asd,asn

...

...

type=magnus-internal/fastcgi exts=php

...

...

修改 obj.conf

编辑 obj.conf 文件以使用前面几节中介绍的插件 SAF 配置特定于 FastCGI 的请求。

以下是修改的 obj.conf 文件示例:

#

# Copyright 2006 Sun Microsystems, Inc. All rights reserved.

# Use is subject to license terms.

#


# You can edit this file, but comments and formatting changes

# might be lost when you use the administration GUI or CLI.



<object name = "default">

		AuthTrans fn="match-browser" browser="*MSIE*" 
						ssl-unclean-shutdown="true"
		NameTrans fn="ntrans-Java EE" name="Java EE"
		NameTrans fn="pfx2dir" from="/mc-icons" 
						dir="/ws7/lib/icons" name="es-internal"
		NameTrans fn="assign-name" from="/fcgi/*" name="fcgi.config"

</object>

<Object name="fcgi.config">

		AuthTrans fn="auth-fastcgi" app-path="/fastcgi/apps/c/simpleAuth" 
				bind-path="localhost:2111"
		Service fn="responder-fastcgi" 
						app-path="/fastcgi_enabled_php_installation_dir/bin/php" 
				app-env="name1=abc"

</object>
...

请注意,通过为不同 URL 模式定义不同对象或将 SAF 映射至不同 MIME 类型,可以采用不同方法调用 FastCGI SAF。

有关 obj.conf 配置和语法的更多信息,请参见《Sun Java System Web Server 7.0 Update 3 Administrator’s Configuration File Reference》中的第 6  章 “Syntax and Use of obj.conf”

配置多个 FastCGI 应用程序

无法通过管理控制台或 CLI 配置多个 FastCGI 应用程序。一种解决方法是,可通过修改 obj.conf 文件来配置多个应用程序。例如:

<If> $uri =~ '^/fcgi/(.*)'>

Service fn="responder-fastcgi" app-path="/export/home/bits/fastcgi/fcgi-2.4.0/examples/$1" app-env="LD_LIBRARY_LIBRARY_PATH=/export/home/bits/fastcgi/fcgi-2.4.0/libfcgi/.libs"</If>

此表达式将创建 <app-path> 进程,该进程不需要单独进行配置。


注 –

无法为多个应用程序配置相同的 bind-path。这会由于通用的 bind-path 而导致启动失败。


配置虚拟主机环境

虚拟主机环境旨在防范与多个虚拟服务器共享 PHP 引擎相关的潜在安全和性能问题。

通过使用 Web Server 7.0 环境变量,您可以分配相同的 PHP 二进制文件,并将单独的引擎绑定到每个虚拟服务器上。应确保每个虚拟服务器具有其自己的 php.ini 文件。


Service fn=responder-fastcgi
        app-path="/path/to/php/php_fcgi"
        bind-path="$(lc($urlhost))"
        req-retry=5
        type="*magnus-internal/fastcgi*"
        app-env="PHPRC=/path/to/users/$(lc($urlhost))/config"
        app-env="PHP_FCGI_CHILDREN=5"
        app-env="PHP_FCGI_MAX_REQUEST=200"
        min-procs=1
        restart-interval=10
        bucket="php-bucket"
        rlimit_cpu=60

现在,Web Server tmp 目录将显示按照处理 PHP 请求的各个虚拟服务器命名的 Unix 域套接字。通过对所有用户使用单个 PHP FastCGI 二进制文件,可以实现此操作。因此,单个二进制文件应具有使用它编译的所有必需插件。上述难题的解决方案是,确保每个用户具有各自所需的 PHP 二进制文件副本。


Service fn=responder-fastcgi
        app-path="/path/to/users/$(lc($urlhost))/php_fcgi"
        bind-path="$(lc($urlhost))"
        req-retry=5
        type="*magnus-internal/fastcgi*"
        app-env="PHPRC=/path/to/users/$(lc($urlhost))/config"
        app-env="PHP_FCGI_CHILDREN=5"
        app-env="PHP_FCGI_MAX_REQUEST=200"
        min-procs=1
        restart-interval=10
        bucket="php-bucket"
        rlimit_cpu=60

此外,也可以通过控制 URI 空间结构,以允许每个应用程序使用不同的 PHP 二进制文件。

例如:

如果 URI 空间结构如下所示:

/app/foo.php

其中 /app 是整个应用程序的名称,在以 PHP 文件结尾的 URI 结构中,它始终是第一个目录。


<If uri~=^/(\w+)/\w+\.php$>
						Service fn=responder-fastcgi
						app-path="/path/to/users/$(lc($urlhost))/$1/php_fcgi"
						bind-path="$(lc($urlhost))_$1"
						req-retry=5
						type=+magnus-internal/fastcgi*"
						app-env="PHPRC=/path/to/users/$(lc($urlhost))/config"
						app-env="PHP_FCGI_CHILDREN=5"
						app-env="PHP_FCGI_MAX_REQUEST=200"
						min-procs=1
						restart-interval=10
						bucket="php-bucket"
						rlimit_cpu=60
</If>

这会调用一个专门生成的 PHP FastCGI 二进制文件,该文件绑定到唯一命名的 Unix 域套接字。因此,其他 PHP 应用程序或其他虚拟服务器将不会受到干扰。不过,此进程会占用很多内存,因为存在许多 PHP 进程。

样例配置文件

以下是一个样例配置文件,用于为 PHP 配置 FastCGI。

<If -f $path>
Service type="magnus-internal/php"
    fn="responder-fastcgi"
    app-path="/opt/coolstack/php5/bin/php-cgi"
    bind-path="localhost:3101"
    app-env="PHPRC=/opt/coolstack/php5"
    app-env="PHP_FCGI_CHILDREN=5"
    app-env="PHP_FCGI_MAX_REQUEST=200"
    app-env="FCGI_WEB_SERVER_ADDRS=127.0.0.1"
    req-retry=5
    restart-interval=10
    bucket="php-bucket"

</If>
<Else>
Service type="magnus-internal/php" fn="set-variable" error="404"
</Else>

排除 FastCGI 插件的故障

Fastcgistub 是一个管理 FastCGI 应用程序进程生命周期的进程管理器。Fastcgistub 将消息记录在 Web Server 临时目录下的 Fastcgistub.log 文件中。如果发生任何错误,检查此文件可以帮助调试问题。

问题:未处理 FastCGI 请求

可能的原因和解决方法如下:

  1. 检查是否加载了 FastCGI 插件。如果在 Web Server 启动过程中显示以下消息,则表示已成功加载该插件。否则,请在 magnus.conf 中检查插件库的路径:FCGI1000: Sun Java System Web Server 7.0 Update 3 FastCGI NSAPI Plugin <build info>

  2. 检查是否在 obj.conf 中正确指定了请求映射。有关 obj.conf 文件的更多信息,请参见 Sun Java System Web Server 管理员配置参考文件

  3. 检查错误日志以找出任何可能的错误消息。

  4. 检查存根二进制文件和 FastCGI 应用程序的权限。如果未授予插件足够的权限,则插件将无法启动存根或应用程序。

  5. 检查 Fastcgistub.log 文件以找出存根端任何可能的错误。可以在 <instances>/logs 中找到日志详细信息。

  6. 如果可能的话,以单机模式运行 FastCGI 应用程序并检查它在运行时是否出现任何问题。

如果抛出任何库相关性错误,请在 obj.conf 中将 LD_LIBRARY_PATH 指定为具有 LD_LIBRARY_PATH=<dependency library paths> 值的 app-env 参数。

问题:无法启动 FastCGI 应用程序。

可能的原因和解决方法如下:

检查 Fastcgistub.log 文件以找出以下日志消息:

..
<pid> process startup failure, trying to restart
...
Even after trying <n> time(s), <application path> process failed to start...no more retries

启动失败的原因之一可能是加载相关库失败。可以通过将相应的库路径指定为 obj.conf 文件中配置的 FastCGI 应用程序的 app-env 参数值来解决此问题。例如:


Service fn="responder_fastcgi" app-path="/fastcgi/c/tux-app" bind-path="localhost:2112" 
app-env="LD_LIBRARY_PATH=/tuxedo/lib"

开发 FastCGI 应用程序

可以使用 Perl、PHP、C 和 Java 开发 FastCGI 应用程序。以下各节简要介绍了使用几种常见编程语言开发此类应用程序的过程。

Procedure执行 FastCGI 应用程序

  1. 停止 Web Server。

  2. 重新启动 Web Server。

  3. 访问应用程序根目录为 "fcgi" 的应用程序。

    例如: http://localhost/fcgi/ListDir.php

FastCGI 应用程序的结构

典型的 FastCGI 应用程序具有以下代码结构:

Initialization code

Start of response loop
		body of response loop
End of response loop

初始化代码只在应用程序初始化时运行一次。初始化代码执行的操作通常比较耗时,例如打开数据库或计算表或位图的值。将 CGI 程序转换为 FastCGI 程序的主要任务是将初始化代码与需要针对每个请求运行的代码分开。

响应循环连续运行,等待客户机请求到达。该循环以对 FCGI_Accept(FastCGI 库中的一个例程)的调用开始。FCGI_Accept 例程将阻止程序执行,直到客户机请求 FastCGI 应用程序为止。客户机请求到达后,FCGI_Accept 将解除阻止并运行一次响应循环主体,然后重新阻止,等待另一个客户机请求。只有在系统管理员或 Web Server 中止 FastCGI 应用程序时,该循环才会终止。

使用 Perl

从 CPAN 下载并安装最新的 FCGI 模块。对于 ActivePerl,可以从 http://aspn.activestate.com/ASPN/Downloads/ActivePerl/PPM/Zips 中下载模块。

有关使用 Perl 编写 FastCGI 应用程序的更多信息,请访问 http://www.fastcgi.com/#TheDevKit

使用 PHP

从 PHP 4.3.0 开始,FastCGI 成为 PHP 引擎支持的配置。要编译支持 FastCGI 的 PHP 4.3.x 或更高版本的引擎,请在构建进程中包括配置开关 --enable-fastcgi,例如:


./configure <other-options> --enable-fastcgi
gmake

编译完成后,php 二进制文件将启用 FastCGI。

使用 PHP 版本 5.1.2 或早期版本(包括 PHP 4.x)时,应配置 FastCGI 插件且 bind-path 的格式为“主机: 端口”。例如,bind-path = "localhost: 3333"。

对于 PHP 版本 5.1.3 和更高版本,bind-path 是可选的。如果指定了此项,其格式应为“主机: 端口”。它可以是字符串。例如,bind-path = "myphpbindpath"。

使用 C/Java

FastCGI 开发工具包提供了用于编写 FastCGI C/Java 应用程序的 API。您可以从 http://www.fastcgi.com/devkit/doc/fcgi-devel-kit.htm 中下载该工具包。

要构建下载的 FastCGI 开发工具包,请执行以下步骤:

  1. 解压缩 tar 文件。此操作将创建一个名为 fcgi-devel-kit 的新目录。

  2. fcgi-devel-kit 目录中执行以下命令序列:

    1. ./configure

    2. make

有关使用 C 编写 FastCGI 应用程序的更多信息,请访问 http://www.fastcgi.com/devkit/doc/fcgi-devel-kit.htm#S3

有关使用 Java 编写 FastCGI 应用程序的更多信息,请访问 http://www.fastcgi.com/devkit/doc/fcgi-java.htm

通过管理控制台在 Web Server 上配置 FastCGI 插件

Procedure通过管理控制台配置 FastCGI 插件

  1. 从以下位置下载启用了 FastCGI 的 Sun Java System Web Server 7.0 PHP Add-On 1.0:http://www.sun.com/download/index.jsp

  2. 在 Web Server 上将 PHP 配置为 FastCGI 服务器。

    1. phppack-5_2_0*.zip 解压缩到 /export/home 中。


      $ cd /export/home; unzip phppack-5_2_0*.zip
    2. 启动 Administration Server。


      $ <webserver-install-root>/admin-server/bin/startserv
    3. 使用管理控制台配置 FastCGI 处理程序。

      1. 登录到管理控制台。

      2. 在“虚拟服务器任务”中单击“编辑虚拟服务器”。

      3. 在“虚拟服务器常规属性”中单击“内容处理”选项卡。

      4. 在“内容处理 - 常规属性”中单击 "FastCGI" 选项卡。

      5. 单击“新建”按钮以添加具有 FastCGI 处理程序映射的新 URI。

        输入以下值:

        • 应用到:选择新 URI,然后输入 /fastcgi/*

        • 角色:从下拉列表中选择响应者

        • 应用程序路径:输入 /export/home/php/bin/php 作为路径。

        • 环境变量:输入以下变量:


          "PHPRC=/export/home/php","LD_LIBRARY_PATH=/export/home/php",
          "LD_LIBRARY_PATH_64=/export/home/php/64"
      6. 单击“确定”按钮。您可能还需要单击“部署”按钮以进行所需的配置。

  3. 创建符号链接。


    $ ln -s <webserver-install-root>/samples/fastcgi <webserver-instance-docroot>
  4. 运行样例。

    • Hello World 样例 URL

      http://<host-name>:<webserver-instance-port>/fastcgi/HelloWorld.php

    • 目录列表样例 URL

      http://<host-name>:<webserver-instance-port>/fastcgi/directory.php

    • 页面计数器样例 URL

      http://<host-name>:<webserver-instance-port>/fastcgi/pageCounter.php

    • 服务器信息样例 URL

      http://<host-name>:<webserver-instance-port>/fastcgi/serverinfo.php

通过 CLI 在 Web Server 上配置 FastCGI 插件

共有 5 个与 FastCGI 处理程序关联的 CLI 命令,如下所示:

Procedure通过 CLI 配置 FastCGI 插件

  1. 调用以下命令来创建 FastCGI 处理程序。


    wadm> create-fastcgi-handler --config=test --vs=test --uri-pattern=/php/* --role=filter
     --app-path=C:\\php\\phppack-5_2_0-windows-i586\\php\\php-cgi.exe

    将创建角色为过滤器的 FastCGI 处理程序。

    有关更多信息,请参见 CLI 参考 create-fastcgi-handler(1)

  2. 调用以下命令来部署配置。


    wadm> deploy-config test

    注 –

    如果第一次创建 FastCGI 处理程序,您应该在部署配置后重新启动实例。


    wadm> restart-instance --config=test localhost

在远程模式下运行启用了 FastCGI 的 PHP 应用程序

可以在远程模式下运行启用了 FastCGI 的 PHP 并配置 Sun Java System Web Server。这样,Web Server 便可将请求传递给远程 PHP 引擎。

Procedure运行启用了 FastCGI 的 PHP 应用程序

  1. 运行启用了 FastCGI 的 PHP。


    $ php -b <hostname>:<port> &

    例如:


    $ php -b localhost:4321 &

    注 –

    通过运行以下命令,可以检查所使用的 PHP 是否启用了 FastCGI:


    $ php -v

    PHP 5.2.5 (cgi-fcgi) (built: May  8 2008 12:50:19)
    Copyright (c) 1997-2007 The PHP Group
    Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies

    在输出中查找 cgi-fcgi 以进行确认。


  2. 使用 CLI 配置 Sun Java System Web Server。

    例如,创建一个名为 test 的 Web Server 实例。

  3. 使用 CLI 执行以下命令:


    wadm> create-fastcgi-handler --config=test --vs=test
     --uri-pattern=/php/* --role=responder --bind-path="localhost:4321"
    wadm> deploy-config test

    将创建一个角色为响应者的 FastCGI 处理程序。

  4. 重新启动实例。


    wadm> restart-instance --config=test localhost

    完成配置后,可以检查来自 Web Server 的请求是否被转发给远程 PHP 引擎。

    1. 将以下样例 PHP 脚本放在实例文档根目录(即 <instance-dir>/docs_directory)的 php 子目录中。


      info.php:
      <?php
      phpinfo();
      ?>
    2. 访问远程 PHP 引擎 URL http://localhost:<webserverport>/php/info.php 以验证请求状态。

FastCGI 应用程序样例

本节包含使用 PHP、Perl 和 C 编写的 FastCGI 应用程序样例。

使用 PHP 编写的响应者应用程序 (ListDir.php)

<?php
 		$dir = "/tmp/";

		// Open a known directory, and proceed to read its contents
		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>

使用 Perl 编写的授权者应用程序 (SimpleAuth.pl)

#!/usr/bin/perl

use FCGI;

while (FCGI::accept >= 0) {
		if( $ENV{'HTTP_AUTHORIZATION'} ) { 
        # This value can be further decoded to get the actual 
			# username and password and then
        # perform some kind of user validation. This program only 
        # checks for the presence of
        # of this environment param and is not really bothered about its value

        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" 目录的内容。

使用 C 编写的过滤器应用程序 (SimpleFilter.c)

#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);
   
				/* clear out stdin */
         	while (EOF != getc(stdin)) {
             	stdinDataSize++;
         	}

				dataToBeRead = filterDataLen;
        	FCGI_StartFilterData();
        	tmp = page; /** just in case fread or fwrite moves our pointer **/


				//start responding
				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; 
					/** at this point your data is in page pointer, so do 
					whatever you want 
               with it before sending it back to the server.
					In this example, no data is manipulated. Only the count of number of 
               times the filter data is read and the total bytes read 
					at the end of every 
               loop is printed. **/	

					dataToBeRead -= numchars;
					loopCount++;
					printf("loop count = %d ... so far read %d bytes <br>", loopCount, 
					(filterDatalen - dataToBeRead));
				}
				printf("\r\n\r\n"); /** send a new line at the end of transfer **/

				fflush(stdout);

				page = tmp; /** restore page pointer **/
				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