如何在nginx中讀取POST上來的資料

2022-08-03 17:30:21 字數 2653 閱讀 4539

nginx中對post資料的讀取是非同步進行的,也就是說你不必在content handler中等待資料讀完然後返回。對客戶端的響應是通過:

兩個呼叫完成,content handler的return並不意味著請求處理的完成。

既然是非同步呼叫,而且caller可以立即返回,那就意味著需要定義乙個**函式:

真正進行資料讀取的是這個函式ngx_http_read_client_request_body,這個函式有兩個引數,乙個是request_rec另外乙個就是**函式指標。

在ngx_http_read_client_request_body這個函式中,進行一系列的檢查和空間分配之後,

//當content-length為0時,nginx直接呼叫**函式。

if (r->headers_in.content_length_n == 0)

} post_handler(r);

如果還有資料沒有讀到:

這句是將pos指標移到目前讀到的資料末尾,保證每次buffer掉資料後,pos始終指向資料末尾的位置。

r->header_in->pos = r->header_in->last;

然後看下還有多少沒有讀到:

rb->rest = r->headers_in.content_length_n - preread;

這裡需要做個判斷,如果沒讀到的資料比當前申請到的buf空間都大的話,那麼就需要重新申請一塊buffer了:

next = &rb->bufs->next;

否則的話就進入:

讀取content body

到這裡,nginx已經為content_body分配好了空間並讀入了隨著請求過來的部分資料。由於只能在讀到header之後才知道資料的實際大小並且request_rec中業已拷貝了,所以要麼在讀到header的時候分配好需要的buf大小,然後執行拷貝,將preread的資料拷貝到這個buf裡,要麼區別處理,即不分配preread到的資料,因為這部分的資料已經拷貝進了header_in,這種情況下,只需分配乙個buf,將其對映到header_in中的資料區,然後對於剩下的尚未讀取到的資料分配新的buf,並將其鏈入buf chain。

顯而易見,後者會節省一次拷貝操作,並且對於特定應用,如果預分配的空間足夠大,那麼完全不需要第二次的考慮操作。nginx用的策略就是後者。

上面的流程其實是乙個優化處理的結果,即在content body隨著request一起提交上來時,就無需設定event並**,直接處理掉就好了,和get方法一樣。

如果在收到請求header時,並非所有的資料都已經提交上來,那麼就需要類似上面的處理,

為r->request_body->buf申請空間,注意這裡在分配空間時,並非完全根據content_length進行,是有上限的,而且一經分配就進入讀取階段,並不會再次分配。結合上面的內容,可見,對於post資料,最多有兩個buf。

rb->buf = ngx_create_temp_buf(r->pool, size);

然後申請乙個buffer chain,並將buffer chain的第乙個buf指向我們剛申請的rb->buf:

cl = ngx_alloc_chain_link(r->pool);

if (cl == null)

cl->buf = rb->buf;

cl->next = null;

最後通過:

*next = cl;

cl初始化完成後就可以將其值賦值給r->request_body->bufs。

並最終同樣進入:

這個函式進行實際的資料讀取工作,邏輯很簡單:呼叫recv,一直讀到返回again或error,或已經讀完了所有資料,error的時候直接返回,again表明還有資料沒讀則設定乙個超時器,加入讀事件進入事件佇列,然後等待下次程序排程執行。

如果已經讀完了,那麼先刪掉上次的定時器。如果

rb->temp_file || r->request_body_in_file_only

兩個值被設定了,那麼就將request_body儲存進乙個臨時檔案中。

最後,帶著已經讀取完畢的post資料,呼叫我們設定的post_handler**函式:

rb->post_handler(r);

相信讀到這裡,post資料如何獲取已經一目了然了。另外,如果設定了標記將post資料寫入file的話,存放file資訊的buf最終會鏈入bufs chain中。

如何在spring中讀取properti

恩,不錯,謝謝分享 如何在spring中讀取properties屬性檔案裡面的資訊 waiwai 一般來說。我們會將一些配置的資訊放在。properties檔案中。然後使用 將配置檔案中的資訊讀取至spring的配置檔案。那麼我們如何在spring讀取properties檔案呢。1.首先。我們要先在...

如何在Nginx中實現負載均衡?

很多時候,在技術或者其他原因下,我們無法通過對 的優化來提高 訪問的速度,這時候,我們就會使用到負載均衡。這裡,我們會講到nginx 的幾種主要的負載均衡的策略 關於 nginx 的安裝和如何利用 nginx session 問題,解決辦法請看之前的文章 1 輪詢 預設方式 顧名思義,這是一種輪流訪...

如何在windows程式中讀取bios內容

今天和夜月兄討論了一下在 windows nt 2000 xp下如何讀取bios資訊,現在把 結果向大家匯報一下。大家都知道,windows接管了對物理 記憶體的直接訪問,而bios資訊存在物理記憶體 的f000 0000處,關鍵就是如何讀取物理記憶體。ntstatuszwopensection o...