FastCGI協議分析


不知道什么時候,就開始有了讓HomeServer支持PHP的念頭。於是分析起了FastCGI協議。FastCGI用於WebServer與WebApplication之間的通訊,例如Apache與PHP程序。

FastCGI協議數據包是8字節對齊的,由包頭(Header)和包體(Body)組成。例如要請求一個index.php的頁面,WebServer首先向WebApp發送一個Request數據包。包頭有個請求ID用於並行工作時,區別不同的請求。

包頭

[版本:1][類型:1][請求ID:2][數據長度:2][填充字節數:1][保留:1]

包體

[角色:2][參數:1][保留:5]

接着,再發送一個Params數據包,用於傳遞執行頁面所需要的參數和環境變量。

包頭

[版本:1][類型:1][請求ID:2][數據長度:2][填充字節數:1][保留:1]

包體

[名稱長度:1或4][值長度:1或4][名稱:變長][值:變長] …

其中,名稱和值的長度占用的字節數是可變,取決於第一個字節(高位)的最高位是否為1,為1則長度是4個字節,否則為1個字節。即如果長度不超過128字節,就用一個字節來保存長度足夠了。

參數發送后還要發送一個沒有包體,只有包頭的空的Params數據包,用來表示參數發送結束。

如果請求頁面時POST方式,還會發送表單數據。這就要用到Stdin數據包了。

包頭

[版本:1][類型:1][請求ID:2][數據長度:2][填充字節數:1][保留:1]

包體

[數據內容:長度在包頭中設置,8字節對齊]

有時候POST的數據大於或等於64KB,就不能使用一個Stdin數據包發送完畢了,需要使用多次Stdin數據包來完成所有數據的傳輸。與Params數據包一樣,結尾要發送一個沒有包體,只有包頭的空的Stdin數據包,用來表示參數發送結束。

至此,WebServer要提供給WebApplication的數據已經發送完畢。接着就接收來自WebApplication的數據了。

數據接收包Stdout與Stdin是差不多的,這里不再描述。不過接收到的數據由HTTP頭和網頁數據兩部分組成,WebServer要對其做一定的處理后才能發送到瀏覽器。同Stdin數據包一樣,WebServer會接收到一個來自WebApplication的Stdout的空數據包,表示接收的Stdout數據已經完畢。

最后,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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM