fastcgi協議解析(nginx)
請求
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 接收請求樣例
memcpy(&fh,recvBuf+0,sizeof(ngx_http_fastcgi_header_t));//FCGI_BEGIN_REQUEST memcpy(&fb,recvBuf+sizeof(ngx_http_fastcgi_header_t),sizeof(ngx_http_fastcgi_begin_request_t)); memcpy(&fp,recvBuf+sizeof(ngx_http_fastcgi_header_t)+sizeof(ngx_http_fastcgi_begin_request_t),sizeof(ngx_http_fastcgi_header_t));//FCGI_PARAMS int paramLen = fp.contentLengthB1*256+fp.contentLengthB0; //816 char paramBuf[1024]; memcpy(paramBuf,recvBuf+sizeof(ngx_http_fastcgi_header_t)*2+sizeof(ngx_http_fastcgi_begin_request_t),paramLen);//environment variables memcpy(&fp,recvBuf+sizeof(ngx_http_fastcgi_header_t)*2+sizeof(ngx_http_fastcgi_begin_request_t)+paramLen,sizeof(ngx_http_fastcgi_header_t));//FCGI_PARAMS memcpy(&fp,recvBuf+sizeof(ngx_http_fastcgi_header_t)*3+sizeof(ngx_http_fastcgi_begin_request_t)+paramLen,sizeof(ngx_http_fastcgi_header_t));//FCGI_STDIN
響應
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);
fastcgi協議解析(nginx)