FastCGI初始:
PHP中fastcgi的实现:
1、开启一个socket监听服务
fcgi_fd=fcgi_listen();
完成socket、bind、listen三步
2、初始化请求对象
fcgi_init_request(&request,fcgi_fd);
struct fcgi_request{
int listen_socket;
int fd,
int id;
int keep;
int closed;
int in_len;
int in_pad;
HashTable* env;
};
3、创建多个CGI解释器子进程
这里子进程的个数默认是0,从配置文件中读取设置到环境变量,然后在程序中读取,然后创建指定数目的子进程来等待处理 Web 服务器的请求。
4、在子进程中接收请求
fcgi_accept_request(&request);
并且把request放入全局变量sapi_globals.server_context,这点很重要,方便了在其他地方对请求的调用。
5、读取数据
fcgi_read_request(fcgi_request* req);
6、执行脚本
7、结束请求
fcgi_finish_requests(&request,1);
消息头
对于fastcgi这种数据收发协议来说,它所发送的每次请求或是回复都有一个可提取的公共部分就是FCGI_Header(请求头),及不管每次发送的是什么消息,都必须会有一个如下格式的请求头
typedefstruct{
unsignedcharversion;//版本unsignedchartype;//操作类型unsignedcharrequestIdB1;//请求idunsignedcharrequestIdB0;unsignedcharcontentLengthB1;//内容长度unsignedcharcontentLengthB0;
unsignedcharpaddingLength;//填充字节的长度unsignedcharreserved;//保留字节
}FCGI_Header;
消息体
1、type为1
开始请求
typedefstruct{
unsignedcharroleB1;//web服务器所期望php-fpm扮演的角色,具体取值下面有unsignedcharroleB0;
unsignedcharflags;//确定php-fpm处理完一次请求之后是否关闭unsignedcharreserved[5];//保留字段
}FCGI_BeginRequestBody;
roleB0=1 是最常用的值,php-fpm接受我们的http所关联的信息,并产生个响应
flags 确定是否与php-fpm建立长连接,为1长连接,为0则在每次请求处理结束之后关闭连接
2、type为3
结束请求
typedefstruct{
unsignedcharappStatusB3;//结束状态,0为正常unsignedcharappStatusB2;
unsignedcharappStatusB1;
unsignedcharappStatusB0;
unsignedcharprotocolStatus;//协议状态unsignedcharreserved[3];
}FCGI_EndRequestBody;
appStatus 共4个字节,用来表示结束状态,0为正常结束
protocolStatus 为协议所处的状态,0为正常状态
3、type为4
typedefstruct{
unsignedcharnameLengthB3;/* nameLengthB0 >> 7 == 0 */unsignedcharnameLengthB2;
unsignedcharnameLengthB1;
unsignedcharnameLengthB0;
unsignedcharvalueLengthB3;/* nameLengthB0 >> 7 == 0 */unsignedcharvalueLengthB2;
unsignedcharvalueLengthB1;
unsignedcharvalueLengthB0;
unsignedcharnameData[(B3 &0x7f) <<24) + (B2 <<16) + (B1 <<8) + B0];
unsignedcharvalueData[valueLength((B3 &0x7f) <<24) + (B2 <<16) + (B1 <<8) + B0];
} FCGI_NameValue;
nameLength 占用4字节,用来说明name的长度
valueLength 4个字节,用来说明value的长度
前8个字节之后紧跟的为nameLength长度的name值,接着是valueLength长度的value值
4、type值为5,6,7
当消息为输入,输出,错误时,它的消息头之后便直接跟具体数据
完整消息record
fastcgi将一个完整的消息称为record,我们每次发送的单位就是record。通过上面的介绍,我们可以总结出常见的记录格式type值record1header(消息头) + 开始请求体(8字节)
3header + 结束请求体(8字节)
4header + name-value长度(8字节) + 具体的name-value
5,6,7header + 具体内容
《完》