请求
NGINX ->[
{(post data) +> (NGX_HTTP_FASTCGI_STDIN)} * N +>
{(environment variables) +> (NGX_HTTP_FASTCGI_PARAMS)} * N +>
(角色和连接设置) +>
(NGX_HTTP_FASTCGI_BEGIN_REQUEST)
] -> fastCGI
NGX_HTTP_FASTCGI_BEGIN_REQUEST : 第一个发送出去的 ngx_http_fastcgi_header_t
角色和连接设置 : ngx_http_fastcgi_begin_request_t结构体
NGX_HTTP_FASTCGI_PARAMS : 环境变量 ,可能有N个
environment variables : 环境变量具体数据包括请求的url use_agent 等等,可能有N个,长度由NGX_HTTP_FASTCGI_PARAMS中的content_length_*指定
NGX_HTTP_FASTCGI_STDIN : 提交的数据 ,可能有N个,
post data : post 上来的数据,可能有N个,长度由NGX_HTTP_FASTCGI_STDIN中的content_length_*指定
数据结构
#define NGX_HTTP_FASTCGI_BEGIN_REQUEST 1
#define NGX_HTTP_FASTCGI_ABORT_REQUEST 2
#define NGX_HTTP_FASTCGI_END_REQUEST 3
#define NGX_HTTP_FASTCGI_PARAMS 4
#define NGX_HTTP_FASTCGI_STDIN 5
#define NGX_HTTP_FASTCGI_STDOUT 6
#define NGX_HTTP_FASTCGI_STDERR 7
#define NGX_HTTP_FASTCGI_DATA 8
typedef struct {
u_char version; //标识FastCGI协议版本 一般为 1
u_char type; //参考上面的宏定义 NGX_HTTP_FASTCGI_*
u_char request_id_hi; //请求id
u_char request_id_lo;
u_char content_length_hi; //请求内容长度
u_char content_length_lo;
u_char padding_length; //填充长度
u_char reserved;
} ngx_http_fastcgi_header_t;
typedef struct {
u_char role_hi; //角色id
u_char role_lo;
u_char flags; // 0 请求完毕后关闭连接 1 请求接收后保持连接
u_char reserved[5];
} ngx_http_fastcgi_begin_request_t;
fastCGI 接收请求样例
// curl -d "{\"name\":\"values\"}" http://172.28.250.184:8099/aa.php
//closesocket(sockConnection);
memcpy(&fh,recvBuf+0,sizeof(FCGI_Header));//FCGI_BEGIN_REQUEST
memcpy(&fb,recvBuf+sizeof(FCGI_Header),sizeof(FCGI_BeginRequestBody));
memcpy(&fp,recvBuf+sizeof(FCGI_Header)+sizeof(FCGI_BeginRequestBody),sizeof(FCGI_Header));//FCGI_PARAMS
int paramLen = fp.contentLengthB1*256+fp.contentLengthB0; //679
int parampadding = fp.paddingLength;//1
char paramBuf[1024];
memcpy(paramBuf,recvBuf+sizeof(FCGI_Header)*2+sizeof(FCGI_BeginRequestBody),paramLen);//environment variable
memcpy(&fp,recvBuf+sizeof(FCGI_Header)*2+sizeof(FCGI_BeginRequestBody)+paramLen+parampadding,sizeof(FCGI_Header));//FCGI_PARAMS
int paramLen2 = fp.contentLengthB1*256+fp.contentLengthB0; //0 第二个PATRAM一般都是0
int parampadding2 = fp.contentLengthB1*256+fp.contentLengthB0; //0 第二个PATRAM一般都是0
memcpy(&fp,recvBuf+sizeof(FCGI_Header)*3+sizeof(FCGI_BeginRequestBody)+paramLen+parampadding,sizeof(FCGI_Header));//FCGI_STDIN
int postLen = fp.contentLengthB1*256+fp.contentLengthB0; //17
int postpadding = fp.contentLengthB1*256+fp.contentLengthB0; //7
char postBuf[256];
memcpy(postBuf,recvBuf+sizeof(FCGI_Header)*4+sizeof(FCGI_BeginRequestBody)+paramLen+parampadding,postLen);//post data
响应
fastCGI ->[
(NGX_HTTP_FASTCGI_END_REQUEST) +>
{(response error data) +> (NGX_HTTP_FASTCGI_STDERR)} * N +>
{(response data) +> (NGX_HTTP_FASTCGI_STDOUT)} * N +>
] -> NGINX
NGX_HTTP_FASTCGI_STDOUT : 输出的正常内容,可能有N个
response data : 相应的数据,长度由NGX_HTTP_FASTCGI_STDOUT中的content_length_*指
NGX_HTTP_FASTCGI_STDERR : 输出的报错内容,可能有N个
response error data : 相应的数据,长度由NGX_HTTP_FASTCGI_STDERR中的content_length_*指
NGX_HTTP_FASTCGI_END_REQUEST : 标识本次响应结束
fastCGI 接收样例
char sendBuf[1024];
char response[]="HTTP/1.1 200 OK\r\nContent-Type:text/html\r\nContent-Length: 7\r\n\r\nWelcome";
fStdout.version=1;
fStdout.type=6;//FCGI_STDOUT
fStdout.requestIdB1=0;
fStdout.requestIdB0=1;
fStdout.contentLengthB1=0;
fStdout.contentLengthB0=strlen(response);
fStdout.paddingLength=0;
fStdout.reserved=0;
fStderr=fStdout;
fStderr.type=7;//FCGI_STDERR
fStderr.contentLengthB0=0;
fEnd = fStderr;
fEnd.type=3;//FCGI_END_REQUEST
memcpy(sendBuf,&fStdout,sizeof(ngx_http_fastcgi_header_t));
memcpy(sendBuf+sizeof(ngx_http_fastcgi_header_t),response,strlen(response));
memcpy(sendBuf+sizeof(ngx_http_fastcgi_header_t)+strlen(response),&fStderr,sizeof(ngx_http_fastcgi_header_t));
memcpy(sendBuf+sizeof(ngx_http_fastcgi_header_t)*2+strlen(response),&fEnd,sizeof(ngx_http_fastcgi_header_t));
send(sockConnection, sendBuf, sizeof(ngx_http_fastcgi_header_t)*3+strlen(response),0);