nginx請求體讀取(二)

2021-09-06 20:21:59 字數 3111 閱讀 7268

2,丟棄請求體

乙個模組想要主動的丟棄客戶端發過的請求體,可以呼叫nginx核心提供的ngx_http_discard_request_body()介面,主動丟棄的原因可能有很多種,如模組的業務邏輯壓根不需要請求體 ,客戶端傳送了過大的請求體,另外為了相容http1.1協議的pipeline請求,模組有義務主動丟棄不需要的請求體。總之為了保持良好的客戶端相容性,nginx必須主動丟棄無用的請求體。下面開始分析ngx_http_discard_request_body()函式:

由於函式不長,這裡把它完整的列出來了,函式的開始同樣先判斷了不需要再做處理的情況:子請求不需要處理,已經呼叫過此函式的也不需要再處理。接著呼叫ngx_http_test_expect() 處理http1.1 expect的情況,根據http1.1的expect機制,如果客戶端傳送了expect頭,而服務端不希望接收請求體時,必須返回417(expectation failed)錯誤。nginx並沒有這樣做,它只是簡單的讓客戶端把請求體傳送過來,然後丟棄掉。接下來,函式刪掉了讀事件上的定時器,因為這時本身就不需要請求體,所以也無所謂客戶端傳送的快還是慢了,當然後面還會將到,當nginx已經處理完該請求但客戶端還沒有傳送完無用的請求體時,nginx會在讀事件上再掛上定時器。

函式同樣還會檢查請求頭中的content-length頭,客戶端如果打算傳送請求體,就必須傳送content-length頭,同時還會檢視其他地方是不是已經讀取了請求體。如果確實有待處理的請求體,函式接著檢查請求頭buffer中預讀的資料,預讀的資料會直接被丟掉,當然如果請求體已經被全部預讀,函式就直接返回了。

接下來,如果還有剩餘的請求體未處理,該函式呼叫ngx_handle_read_event()在事件處理機制中掛載好讀事件,並把讀事件的處理函式設定為ngx_http_discarded_request_body_handler。做好這些準備之後,該函式最後呼叫ngx_http_read_discarded_request_body()介面讀取客戶端過來的請求體並丟棄。如果客戶端並沒有一次將請求體發過來,函式會返回,剩餘的資料等到下一次讀事件過來時,交給ngx_http_discarded_request_body_handler()來處理,這時,請求的discard_body將被設定為1用來標識這種情況。另外請求的引用數(count)也被加1,這樣做的目的是客戶端可能在nginx處理完請求之後仍未完整傳送待傳送的請求體,增加引用是防止nginx核心在處理完請求後直接釋放了請求的相關資源。

ngx_http_read_discarded_request_body()函式非常簡單,它迴圈的從鏈結中讀取資料並丟棄,直到讀完接收緩衝區的所有資料,如果請求體已經被讀完了,該函式會設定讀事件的處理函式為ngx_http_block_reading,這個函式僅僅刪除水平觸發的讀事件,防止同一事件不斷被觸發。

再來看一下讀事件的處理函式ngx_http_discarded_request_body_handler,這個函式每次讀事件來時會被呼叫,先看一下它的原始碼:

函式一開始就處理了讀事件超時的情況,之前說到在ngx_http_discard_request_body()函式中已經刪除了讀事件的定時器,那麼什麼時候會設定定時器呢?答案就是在nginx已經處理完該請求,但是又沒有完全將該請求的請求體丟棄的時候(客戶端可能還沒有傳送過來),在ngx_http_finalize_connection()函式中,如果檢查到還有未丟棄的請求體時,nginx會新增乙個讀事件定時器,它的時長為lingering_timeout指令所指定,預設為5秒,不過這個時間僅僅兩次讀事件之間的超時時間,等待請求體的總時長為lingering_time指令所指定,預設為30秒。這種情況中,該函式如果檢測到超時事件則直接返回並斷開連線。同樣,還需要控制整個丟棄請求體的時長不能超過lingering_time設定的時間,如果超過了最大時長,也會直接返回並斷開連線。

如果讀事件發生在請求處理完之前,則不用處理超時事件,也不用設定定時器,函式只是簡單的呼叫ngx_http_read_discarded_request_body()來讀取並丟棄資料。

Openresty 讀取請求體

由於nginx預設不讀取請求體的資料,因此當lua通過ngx.var.request body的方式獲取請求體時會發現資料為空,那麼,該如何獲得請求體的資料呢?方式一 lua need request body 語法 lua need request body 預設值 off 環境 http ser...

請求行,請求頭,請求體

1.請求報文 請求行 請求頭 請求資料 空行 請求行求方法字段 url欄位和http協議版本 例如 get index.html http 1.1 get方法將資料拼接在url後面,傳遞引數受限 請求方法 get post head put delete options trace connect ...

請求行 請求頭 請求體

請求行 是請求方法,get和post是最常見的http方法,除此以外還包括delete head options put trace。為請求對應的url位址,它和報文頭的host屬性組成完整的請求url。是協議名稱及版本號。請求頭 是http的報文頭,報文頭包含若干個屬性,格式為 屬性名 屬性值 服...