FastCGI规范与编程

本规范 从应用程序的角度,指明 在FastCGI应用程序 和 Web服务器之间的接口。许多Web服务器同FastCGI相关的一些特性,如应用程序管理设施,与应用程序和服务器的接口无关,这里就不提了。

本规范是针对Unix(准确地说,是针对支持Berkley套接字的POSIX系统).规范的绝大部分是一个简单的通信协议,与机器字节顺序无关。主要通过与传统的CGI/1.1的Unix实现比较,来介绍FastCGi。

FastCGI被设计成 支持long-lived应用程序进程,也就是应用服务器

传统CGI建立一个应用进程,用它来响应一个请求,该进程然后退出。FastCGI的初始状态比CGI/1.1的更精炼,因为FastCGI进程开始时并不会连接到任何东西,它没有传统的打开文件stdin,stdout和stderr,也不从环境变量中取得额外的信息。FastCGI的初始状态只是监听一个从服务器接受连接的socket。

在一个FastCGI进程在它监听的socket接受一个连接后,该进程执行一个简单的协议来接收和发送数据。协议有2个目的,首先,协议 将 多个无关的FastCGI请求 复用到一个传输连接上,这可支持那些使用事件驱动或者多线程编程技术的 能够处理多个并发请求的应用程序。其次,在每个请求中,协议可双向提供多个无关的数据流。这样,stdout和stderr数据可通过一个从应用程序到服务器的单个传输连接来传送而不是CGI/1.1那一嗯要求不同的管道。

一个FastCGI应用 扮演多个明确的角色中的一个,最常见的是 响应器,应用程序在响应器中收取同HTTP请求相关的所有信息,然后生成一个HTTP响应;这也是CGI/1.1扮演的角色。第二个角色是 授权人。 应用程序从授权人中接收同一个HTTP请求相关的所有信息,然后生成一个授权/不授权的决定。第三个角色是 过滤器,应用程序从过滤器中接受所有同HTTP请求相关的所有信息,加上一个从存贮在服务器中的文件中的额外的数据流,然后生成一个数据流的过滤版本 作为HTTP响应。这个框架可扩展,所以更多FastCGI可以后定义。

初始进程状态

参数表

服务器默认会建立一个参数表,含有一个元素:应用程序的名称(可执行文件路径的最后一部分)。服务器可提供指定一个不同的应用程序名称,或者一个更详尽的参数表。

注意:该可执行文件可能是一个脚本文件(以#!开始的文本文件).这种情况下,建立的应用参数表在execve手册中有描述。

文件描述符


如果应用程序开始执行,服务器就打开一个文件描述符 FCGI_LISTENSOCK_FILENO,这个描述符 指向一个由服务器建立的监听socket.FCGI_LISTENSOCK_FILENO 等同于STDIN_FILENO。当应用程序开始执行时,标准的描述符STDOUT_FILENO和 STDERR_FILENO被关闭。应用程序判断是被使用CGI还是FastCGI调用的可靠方法是 调用getpeername(FCGI_LISTENSOCK_FILENO),如果返回-1 ,并且errno被设为ENOTCONN的话,就是使用FastCGI方式。

服务器的连接选择Unix流管道(AF_UNIX)还是TCP/IP(AF_INET),是隐含在FCGI_LISTENSOCK_FILENO Socket的内部状态中的。

环境变量

服务器可能利用环境变量传递参数给应用程序。这个规范定义了一个变量FCGI_WEB_SERVER_ADDRS。规范将来可定义更多变量。服务器提供了一中绑定到其他环境变量的方式,比如PATH变量

符号

我们使用C语言符号来定义协议消息格式。所有的结构元素 都用 unsigned char类型来定义。以便一个ISO C编译器可用明显的方式编排它们,没有任何补齐。
在结构体里定义的第一个字节被首先传输,然后在传输第2个字节。

我们用两个约定来简化我们的定义:
1.如果2个相邻的结构体元素 除了后缀B1和B0外,其他完全相同,这就意味着,这两个元素可能被看作一个数字,算成B1<<8 + B0  这个数字的名字就是 结构体元素的名字除掉后缀。这个约定一般用来处理那些超过2个字节的数字。

2.扩展C结构体,允许这种形式
        struct {
            unsigned char mumbleLengthB1;
            unsigned char mumbleLengthB0;
            ... /* other stuff */
            unsigned char mumbleData[mumbleLength];
        };

这表示,该结构体 长度可变,长度由前面的元素指定。

接受传输连接

一个FastCGI应用程序在一个由文件描述符FCGI_LISTENSOCK_FILENO定义的socket上调用accept() 来接受一个心的传输连接。如果accept()成功执行,FCGI_WEB_SERVER_ADDRS环境变量被绑定,应用程序立即执行下面的处理
1)FCGI_WEB_SERVER_ADDRS:这个值是服务器 有效IP地址的列表
如果FCGI_WEB_SERVER_ADDRS被绑定,应用程序为列表中的成员 检查新连接的对方的的IP。如果检查失败(包括连接没有使用 TCP/IP传输的情况),应用程序将关闭这个连接。

2)FCGI_WEB_SERVER_ADDRS用逗号分开,一个合法的例子
FCGI_WEB_SERVER_ADDRS=199.170.183.28,199.170.183.71

一个应用可以接受几个并发的传输连接,但这不是必要的.

记录

应用程序执行一个使用简单协议从服务器送过来的请求。协议的细节依赖于应用程序的角色,但一般来讲,服务器首先发送一些参数和其他数据给应用程序,然后应用程序发送结果数据给服务器,最后应用程序发送给服务器一个指示,说请求已经完成。

所有的数据都通过 传输连接的FastCGI records传送。FastCGI records完成两件事第一,记录将复用 几个不相关的FastCGI请求到传输连接 上。复用支持 应用程序处理多个
使用事件驱动或者多线程编程技术的并发请求。第二,记录在单个请求中提供多个不同方向的不相关的数据流.以这种方式,stdout 和 stderr能通过单个传输连接,从应用程序传送到服务器,而不是要求不同的连接。

        typedef struct {
            unsigned char version;
            unsigned char type;
            unsigned char requestIdB1;
            unsigned char requestIdB0;
            unsigned char contentLengthB1;
            unsigned char contentLengthB0;
            unsigned char paddingLength;
            unsigned char reserved;
            unsigned char contentData[contentLength];
            unsigned char paddingData[paddingLength];
        } FCGI_Record;


一个FastCGI记录含有固定长度的前缀,后面跟着的是可变长度的内容和填充字节。
一个记录还有7个元素:
version: 标示FastCGI协议的版本。本规范的版本FCGI_VERSION_1
type:标示FastCGI记录的类型。也就是 记录执行的一般功能.具体的功能后面有描述
requestId: 标示该记录属于哪一个FastCGI请求
contentLength: 后面的contentData元素的字节个数
paddingLength: 后面的paddingData元素的字节个数
contentData: 在0到65535之间,不同的记录类型有不同的意义
padddingData:在0到255之间,填充字节。可以被忽略

使用不严格的C结构体初始化语法来指定 常量FastCGI记录。忽略version元素,忽略padding,
将requestId看作一个数字。
{FCGI_END_REQUEST, 1, {FCGI_REQUEST_COMPLETE,0}}

是一个   类型为FCGI_END_REQUEST,
        requestId 为 1,
        contentData == {FCGI_REQUEST_COMPLETE,0}的记录


填充


作者:Gavin   更新日期:2006-10-19
来源:upsdn.net   浏览次数:

相关文章

相关评论   发表评论