Nginx HTTP框架是如何介入請求

2022-05-02 22:51:10 字數 2815 閱讀 5959

參考資料 《深入理解nginx>(陶輝)

nginx是乙個事件驅動構架的web伺服器,在上次的部落格中我們可以看到nginx是如何驅動事件的處理的。

本次將介紹http框架是如何介入跟處理http網路事件的。因為書上的思路已經足夠清晰而且內容比較獨立,因此本次基本上就把本章的重點記錄一下。

http框架存在的目的

1.nginx事件框架主要是針對傳輸層的tcp的,作為web伺服器http模組需要處理的則是http,http框架必須要針對基於tcp的事件框架解決好http的網路傳輸、解析、組裝等問題。

2.雖然事件驅動構架在效能上是不錯的,但是http模組的業務通常較複雜,http框架的存在則可以讓我們遮蔽事件驅動架構,盡量只關注業務,提供開發效率。

新連線建立時的行為

在上次部落格的最後可以看到,在ngx_event_accept方法建立連線的最後一步,將會呼叫ngx_listening_t監聽結構體的handler方法。這時候http框架就開始介入請求了。

http框架在初始化時就會將每個監聽ngx_listening_t結構體的handler方法設為ngx_http_init_connection方法,該方法執行流程如下圖:

其中定時器中的超時時間是nginx.conf配置檔案中指定的client_header_timeout,後面的超時時間設定也是這個值。

第一次可讀事件的處理

當tcp連線上第一次出現可讀事件時,將會呼叫ngx_http_init_request方法初始化這個http請求

該方法主要做了3件事情:

1.對請求構造ngx_http_request_t結構體並初始化部分引數;

2.修改讀事件的**方法為ngx_http_process_request_line

3.呼叫上面的**方法解析http請求行

6.讀事件被觸發,這是需要在使用者態的程序空間分配記憶體,用來把核心緩衝區上的tcp流複製到使用者態的記憶體中。

這一步將在ngx_connection_t的記憶體池中分配一塊記憶體,記憶體塊的大小與nginx.conf檔案中的client_header_buffer_size配置項引數一致。

ngx_connection_t結構體的buffer指標以及ngx_http_request_t結構體的header_in指標共同指向這塊記憶體緩衝區。

接收http請求行

在初始化請求之後,將呼叫ngx_http_process_request_line方法接收http請求行。

因為請求行的長度是不定的,這意味著在讀事件被觸發時,核心套接字緩衝區的大小未必足夠接收到全部的http請求行。

因此呼叫一次ngx_http_process_request_line方法不一定能夠接收完完整的http請求行,該方法會被多次排程。下圖展示了該方法的流程

該方法會呼叫recv方法把linux核心套接字緩衝區中的tcp流複製到header_in緩衝區中。

header_in的型別是ngx_buf_t,它的pos成員和last成員指向的位址之間的記憶體就是收到的未解析的字元流。

4.在本次沒有接收到tcp流的時候,告訴事件驅動程式繼續檢測這個讀事件,然後該方法就結束。在該讀事件準備好的時候,該方法將被再次排程。

5.在接收到tcp流後,用狀態機(ngx_http_parse_request_line方法)解析已經接收到的tcp字元流,確認其是否構成完整的http請求行。

7.如果ngx_http_parse_request_line方法返回ngx_ok,表示已經成功地接收到完整的請求行。這一步將把請求行的的資訊設定到ngx_http_request_t結構體的相應成員中

(request_line、uri、method_name、http_protocol、args等)。

11.接收完http請求行後,把讀事件的**方法更改為ngx_http_request_headers準備接收http頭部。

接收http頭部

跟http請求行一樣,http頭部也屬於可變長度的字串,它與http請求行和包體間都是通過換行符來區分的。

下圖展示了http框架使用ngx_http_process_request_headers方法接收、解析http頭部的流程

6.呼叫ngx_http_parse_header_line方法解析緩衝區的字元流。這個方法有3個返回值:

返回ngx_ok時,表示解析出一行http頭部;返回ngx_http_parse_header_done時,表示已經解析出了完整的http頭部;

返回ngx_again時,表示還需要接收到更多的字元流才能繼續解析;除此之外的錯誤情況,將傳送400錯誤給客戶端。

7.解析出的http頭部資訊設定到ngx_http_request_t結構體headers_in成員的headers鍊錶中。

9.當ngx_http_parse_header_line方法返回ngx_http_parse_header_done時,將會根據http頭部中的host欄位情況,

呼叫ngx_http_find_virtual_server方法找到對應的虛擬主機配置塊。ngx_http_request_t結構體裡的srv_conf、loc_conf成員被重新設定,以指向正確的虛擬主機。

在接收到完整的http頭部後,已經有足夠的必要資訊開始在業務上處理http請求了。下一節將說明http框架是如何召集負責具體功能的各http模組合作處理請求的。

Nginx Http框架的理解

nginx http框架的理解 http框架是nginx基礎框架的一部分,nginx的其它底層框架如master worker程序模型 event模組 mail 模組等。http框架 主要有2個模組組成 ngx http module和ngx http core module 我們編寫的http模組...

nginx HTTP框架提供的變數

1.arg 引數名 url中某個具體引數的值 2.query string 預args變數完全相同 3.args 全部url引數 4.is args 如果請求url中有引數則返回?否則返回空 5.content length http請求中標識包體長度的content length頭部的值 6.co...

linux kail recon ng框架的介紹

recon ng是由python編寫的乙個開源的web偵察 資訊收集 框架。recon ng非常強大,它可以自動的進行資訊收集和網路偵察。linux kail中recon ng的安裝 git clone啟動時它會提示你 key not set,也就是api沒設定,因為呼叫裡面的某些外部服務模組的時候...