不知道何時,就開始有了讓HomeServer支持PHP的念頭。因而分析起了FastCGI協議。FastCGI用於WebServer與WebApplication之間的通信,例如Apache與PHP程序。php
FastCGI協議數據包是8字節對齊的,由包頭(Header)和包體(Body)組成。例如要請求一個index.php的頁面,WebServer首先向WebApp發送一個Request數據包。包頭有個請求ID用於並行工做時,區別不一樣的請求。瀏覽器
包頭
[版本:1][類型:1][請求ID:2][數據長度:2][填充字節數:1][保留:1]
包體
[角色:2][參數:1][保留:5]app
接着,再發送一個Params數據包,用於傳遞執行頁面所須要的參數和環境變量。spa
包頭
[版本:1][類型:1][請求ID:2][數據長度:2][填充字節數:1][保留:1]
包體
[名稱長度:1或4][值長度:1或4][名稱:變長][值:變長] …io
其中,名稱和值的長度佔用的字節數是可變,取決於第一個字節(高位)的最高位是否爲1,爲1則長度是4個字節,不然爲1個字節。即若是長度不超過128字節,就用一個字節來保存長度足夠了。
參數發送後還要發送一個沒有包體,只有包頭的空的Params數據包,用來表示參數發送結束。ast
若是請求頁面時POST方式,還會發送表單數據。這就要用到Stdin數據包了。
包頭
[版本:1][類型:1][請求ID:2][數據長度:2][填充字節數:1][保留:1]
包體
[數據內容:長度在包頭中設置,8字節對齊]變量
有時候POST的數據大於或等於64KB,就不能使用一個Stdin數據包發送完畢了,須要使用屢次Stdin數據包來完成全部數據的傳輸。與Params數據包同樣,結尾要發送一個沒有包體,只有包頭的空的Stdin數據包,用來表示參數發送結束。表單
至此,WebServer要提供給WebApplication的數據已經發送完畢。接着就接收來自WebApplication的數據了。cgi
數據接收包Stdout與Stdin是差很少的,這裏再也不描述。不過接收到的數據由HTTP頭和網頁數據兩部分組成,WebServer要對其作必定的處理後才能發送到瀏覽器。同Stdin數據包同樣,WebServer會接收到一個來自WebApplication的Stdout的空數據包,表示接收的Stdout數據已經完畢。fastcgi
最後,WebApplication會發送一個包含狀態的EndRequest數據包,至此,一次頁面請求處理完畢。
下面給出一些相關結構參考。
通用包頭:
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; }FCGI_Header; typedef struct { unsigned char roleB1; unsigned char roleB0; unsigned char flags; unsigned char reserved[5]; } FCGI_BeginRequestBody; typedef struct { FCGI_Header header; FCGI_BeginRequestBody body; } FCGI_BeginRequestRecord; typedef struct { unsigned char appStatusB3; unsigned char appStatusB2; unsigned char appStatusB1; unsigned char appStatusB0; unsigned char protocolStatus; unsigned char reserved[3]; } FCGI_EndRequestBody;
每次請求頁面時,傳遞給PHP程序的參數:
SCRIPT_FILENAME,
QUERY_STRING,
REQUEST_METHOD,
CONTENT_TYPE,
CONTENT_LENGTH,
SCRIPT_NAME,
REQUEST_URI,
DOCUMENT_URI,
DOCUMENT_ROOT,
SERVER_PROTOCOL,
GATEWAY_INTERFACE,
SERVER_SOFTWARE,
REMOTE_ADDR,
REMOTE_PORT,
SERVER_ADDR,
SERVER_PORT,
SERVER_NAME,
REDIRECT_STATUS,
HTTP_ACCEPT,
HTTP_ACCEPT_LANGUAGE,
HTTP_ACCEPT_ENCODING,
HTTP_USER_AGENT,
HTTP_HOST,
HTTP_CONNECTION,
HTTP_CONTENT_TYPE,
HTTP_CONTENT_LENGTH,
HTTP_CACHE_CONTROL,
HTTP_COOKIE,
HTTP_FCGI_PARAMS_MAX
好像不少,可是不少空值的,能夠省去,不發送之,便可。
轉自:http://xiaoxia.org/2009/10/05/fastcgi-protocol-analysis/