fastcgi協議分析與例項
1.序言
最近在用c++實現一個簡易web伺服器。在實現之前大體理了一下一個web伺服器主要咋樣實現。當時單純的認為只需要將瀏覽器發來的http請求解析,找到對應的檔案,然後給瀏覽器一個響應,把其要獲取的檔案發給它就完事。可是寫了沒幾天就遇到了瓶頸。因為我們的瀏覽器並不能解析動態的PHP檔案,那麼如果獲取的http請求的請求檔案為.php檔案我們該雜麼辦呢?
2.將.php轉換為.html的php-fpm
我們都知道php是一門解釋型語言,當php在執行時,php核心都會為我們呼叫php直譯器來幫我們解釋程式。而我們的php-fpm相比php核心也具有此功能(事實上,php最新版本以把php-fpm當做一個補丁打在php核心之中了)
php-fpm的安裝方式為
<code class="hljs lasso has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">sudo apt<span class="hljs-attribute" style="box-sizing: border-box;">-get</span> install php5<span class="hljs-attribute" style="box-sizing: border-box;">-fpm</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
顯然php-fpm能夠幫我們解決1中遇到的問題。具體解決過程為:當我們的web伺服器收到.php檔案時,就讓php-fpm把其解釋(翻譯)成html格式的檔案(事實上php-fpm正是幹這個事的),然後我們的web伺服器將翻譯出來的.html檔案發給瀏覽器就萬事大吉了。。
3.php-fpm與webserver互動問題
我想我在2中已經用最少的文字闡述清楚了當我們收到.php檔案應該雜麼辦了。道理的確簡單,問題在於我們如何才能讓php-fpm幫我們解析我們想要翻譯成.html檔案的.php檔案呢?(要知道php-fpm可不是人,它可聽不懂人話的)。為了能與php-fpm愉快的合作,我們就得使用它能聽得懂的語言(協議)。說道這fastcgi就正式登場了,沒錯php-fpm所能聽的懂的語言正是fastcgi,我們可以通過fastcgi協議來和php-fpm進行互動來達成我們的目的
4.fastcgi協議
如果讀者之前有學習過http或者TCP/IP協議,那麼我想通過我接下來簡單粗暴的講解你一定能很快掌握此協議
(1)訊息頭(請求頭)
對於fastcgi這種資料收發協議來說,它所傳送的每次請求或是回覆(我之後的敘述中叫它們為訊息)都有一個可提取的公共部分就是FCGI_Header(請求頭),及不管每次傳送的是什麼訊息,都必須會有一個如下格式的請求頭
其C語言格式(其支援各種語言)定義如下
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> version; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//版本</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> type; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//操作型別</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> requestIdB1; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//請求id</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> requestIdB0; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> contentLengthB1; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//內容長度</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> contentLengthB0; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> paddingLength; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//填充位元組的長度</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> reserved; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//保留位元組</span> }FCGI_Header;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>
觀察上面的訊息請求頭我們可以發現一個請求頭只有8個位元組大小,其每個欄位的解釋如下
.version:用來表示FCGI的版本資訊,如果是web伺服器給php-fpm傳送的訊息,請求頭中只需要將其置0就可以
.type:此欄位用來說明每次所傳送訊息的型別,其具體值可以為如下
type值 | 具體含義 |
---|---|
1 | 在與php-fpm建立連線之後傳送的第一個訊息中的type值就得為1,用來表明此訊息為請求開始的第一個訊息 |
2 | 異常斷開與php-fpm的互動 |
3 | 在與php-fpm互動中所發的最後一個訊息中type值為此,以表明互動的正常結束 |
4 | 在互動過程中給php-fpm傳遞環境引數時,將type設為此,以表明訊息中包含的資料為某個name-value對 |
5 | web伺服器將從瀏覽器接收到的POST請求資料(表單提交等)以訊息的形式發給php-fpm,這種訊息的type就得設為5 |
6 | php-fpm給web伺服器回的正常響應訊息的type就設為6 |
7 | php-fpm給web伺服器回的錯誤響應設為7 |
還有一些其他的不常用的type值,我們這裡就不提了,上述type值的詳細含義可以在這裡獲得
戳這裡
.requestId:此欄位佔倆個位元組,它表示這某個特有的互動,因為php-fpm(可以理解為伺服器)可以同時處理多個互動
.contentLength:此欄位也佔2個位元組,它用來表示此訊息中的訊息體中資料的長度(我們上面一直說的請求頭也可以叫其訊息頭),我們可以據此在讀訊息時,能夠知道讀多長能讀出一條完整的訊息
.paddingLength:填充長度的值,為了提高處理訊息的能力,我們的每個訊息大小都必須為8的倍數,此長度標示,我們在訊息的尾部填充的長度
.reserved:保留欄位
以上便是我們對訊息頭8位元組中每個位元組所表達的含義的分析
下圖為php-fpm給web伺服器傳輸的一個具體訊息的訊息頭(8位元組)內容
.序列0(對應version欄位)的數值為01,代表php-fpm的版本資訊
.序列1(對應type欄位)的數值為03,根據上面對type值含義的解釋,可以知道這個訊息將標誌這此次互動的結束
.序列2,3 00,01說明此次互動的請求ID為01
.序列4,5 00,08標示這在序列7之後的訊息體的長度為8
.序列6標示填充位元組為0,及本身訊息體以是8的位元組了
.序列7將訊息的保留位元組設為0
通過上述具體例項,我想大家大概可以明白當我們得到fastcgi協議的一個訊息頭,我們能獲取那些資訊
(2)訊息體(請求體)
(1)中我們簡單介紹了一個訊息的訊息頭,由於所有的訊息都共用這個訊息頭,所以介紹起來也簡單,但是訊息體就不同了。對於請求開始(及一次互動的第一個)的訊息,有其自己的訊息體格式,對於請求結束(一次互動的最後一個)的訊息,有其自己的訊息體格式,對於傳遞PARAMS引數……訊息頭type欄位標示的訊息型別不同,對應的訊息體的格式就可能不同
接下來我會根據type值的不同來介紹各類訊息體結構
1.type為1
讀者對照上面介紹的type值的含義可知,此類訊息為互動剛開始所發的第一個訊息,其訊息體結構c定義如下
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> roleB1; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//web伺服器所期望php-fpm扮演的角色,具體取值下面有</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> roleB0; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> flags; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//確定php-fpm處理完一次請求之後是否關閉</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> reserved[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">5</span>]; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//保留欄位</span> }FCGI_BeginRequestBody;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
根據上述可知type值為1的訊息(標識開始請求)的訊息的訊息體為固定大小8位元組,其中各個欄位的具體含義如下
.role:此欄位佔2個位元組,用來說明我們對php-fpm發起請求時,我們想讓php-fpm為我們扮演什麼角色(做什麼,或理解為雜麼做),其常見的3個取值如下:
role值 | 具體含義 |
---|---|
1 | 最常用的值,php-fpm接受我們的http所關聯的資訊,併產生個響應 |
2 | php-fpm會對我們的請求進行認證,認證通過的其會返回響應,認證不通過則關閉請求 |
3 | 過濾請求中的額外資料流,併產生過濾後的http響應 |
.flags:欄位確定是否與php-fpm建立長連線,為1長連線,為0則在每次請求處理結束之後關閉連線
.reserved:保留欄位
2.type值為3
type值為3表示結束訊息,其訊息體的c定義如下
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> appStatusB3; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//結束狀態,0為正常</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> appStatusB2; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> appStatusB1; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> appStatusB0; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> protocolStatus; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//協議狀態</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> reserved[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>]; }FCGI_EndRequestBody;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>
同樣我們可以看出結束訊息體也為固定8位元組大小
其各欄位的具體含義如下ph
.appStatus:此欄位共4個位元組,用來表示結束狀態,0為正常結束
.protocolStatus:為協議所處的狀態,0為正常狀態
.reserved:為保留位元組
3.type為4
此值表示此訊息體為傳遞PARAMS(環境引數),環境引數其實就是name-value對,我們可以使用自己定義的name-value傳給php-fpm或者傳遞php-fpm已有的name-value對,以下為我們後面例項將會使用到的php-fpm以有的name-value對如下
name | value |
---|---|
SCRIPT_FILENAME | value值為具體.php檔案所處的位置php-fpm將根據value值找到所要處理的.php檔案 |
REQUEST_METHOD | value值一般為GET,表示http請求的方式 |
好了回到主體,當我們要傳遞訊息體為環境引數時,我們的訊息體的格式如下
<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typedef</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> nameLengthB3; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* nameLengthB0 >> 7 == 0 */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> nameLengthB2; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> nameLengthB1; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> nameLengthB0; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> valueLengthB3; <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* nameLengthB0 >> 7 == 0 */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> valueLengthB2; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> valueLengthB1; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> valueLengthB0; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> nameData[(B3 & <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x7f</span>) << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">24</span>) + (B2 << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>) + (B1 << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>) + B0]; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">unsigned</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">char</span> valueData[valueLength ((B3 & <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0x7f</span>) << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">24</span>) + (B2 << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">16</span>) + (B1 << <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">8</span>) + B0]; } FCGI_NameValue;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>
可以看出訊息體前8個位元組為固定的,其欄位具體含義為
.nameLength:此欄位佔用4位元組,用來說明name的長度
.valueLength:此欄位為4個位元組,用來說明value的長度
前8個位元組之後緊跟的為nameLength長度的name值,接著是valueLength長度的value值
4.type值為5,6,7
當訊息為輸入,輸出,錯誤時,它的訊息頭之後便直接跟具體資料
(3)完整訊息record
fastcgi將一個完整的訊息稱為record,我們每次傳送的單位就是record。通過上面的介紹,我們可以總結出常見的記錄格式
type值 | record |
---|---|
1 | header(訊息頭) + 開始請求體(8位元組) |
3 | header + 結束請求體(8位元組) |
4 | header + name-value長度(8位元組) + 具體的name-value |
5,6,7 | header + 具體內容 |
5.fastcgi協議使用例項
前面我們已經介紹了php-fpm的安裝方法,其安裝好之後,預設的通訊方式為unix本地域套接字通訊,具體檢視
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">/etc/php5/fpm/pool<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.d</span>/www<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.conf</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
截圖如下
而我們的接下來的例項與php-fpm為TCP通訊的方式,所以,我們得在這裡改下配置,具體修改結果如下所示
我將ip地址設成了127.0.0.1 監聽埠設為9000
修改之後需要重啟php-fpm程式,如下
<code class="hljs bash has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">sudo</span> service php5-fpm restart</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>
好了準備工作結束,此時編譯執行這裡的程式碼,我們就可以將內容為
<code class="hljs xml has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">html</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">body</span>></span> <span class="php" style="box-sizing: border-box;"><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;"><?php</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">echo</span> <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"hello"</span>; <span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">?></span></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">body</span>></span></code>
相關文章
- FastCGI協議分析AST協議
- 分散式一致性協議Raft原理與例項分散式協議Raft
- React元件/元素與例項分析React元件
- ActiveSync 協議選項協議
- 深入理解 FastCGI 協議以及在 PHP 中的實現AST協議PHP
- http協議分析HTTP協議
- WireShark——IP協議包分析(Ping分析IP協議包)協議
- QQ 快速登入協議分析與實現協議
- 路由協議與閘道器協議路由協議
- wireshark 分析TCP協議TCP協議
- CRLF Injection漏洞的利用與例項分析
- ONEMT 與 Flexion Mobile 達成一項新合作協議Flex協議
- 生成樹協議與多生成樹協議協議
- 【協議】AAA Radius協議的常用報文分析協議
- YACC 例項分析
- CGI與FastCGIAST
- Zookeeper的ZAB協議與Paxos協議區別協議
- javascript強制閱讀註冊協議指定時間程式碼例項JavaScript協議
- SSL與TLS協議TLS協議
- 透視RPC協議:SOFA-BOLT協議原始碼分析RPC協議原始碼
- Redis 例項分析工具Redis
- 非同步(一):Promise深入理解與例項分析非同步Promise
- 【原創】Oracle execute plan 原理分析與例項分享Oracle
- HTTP協議分析及攻防方法HTTP協議
- Java安全之RMI協議分析Java協議
- DHCP協議工作流程分析協議
- UDP協議抓包分析 -- wiresharkUDP協議
- 計算網路之MSTP協議與VRRP協議協議VR
- Http與Https協議HTTP協議
- IS-IS協議原理與配置協議
- 分散式概念與協議分散式協議
- 3.協議與埠協議
- 國密SSL協議與標準TLS協議的區別協議TLS
- 網路基礎與協議入門——(2)TCP協議重點協議TCP
- 網路基礎與協議入門——(1)HTTP協議重點協議HTTP
- Dubbo原始碼分析(一)Dubbo與Spring整合例項原始碼Spring
- 【網路協議】IP協議、ARP協議、RARP協議協議
- for迴圈的例項分析