nginx讀取請求體
請求體的讀取一般發生在nginx的content handler中,一些nginx內置的模塊,比如proxy模塊,fastcgi模塊,uwsgi模塊等,這些模塊的行為必須將客戶端過來的請求體(如果有的話)以相應協議完整的轉發到後端服務進程,所有的這些模塊都是調用了ngx_http_read_client_request_body()接口來完成請求體讀取。值得註意的是這些模塊會把客戶端的請求體完整的讀取後才開始往後端轉發數據。
上面我們已經開始處理http request header了,接下來,如果請求中有body內容,那麽需要處理body了。這裏你肯定不會想要去阻塞式的讀取body吧?body的長度可大可小,網絡環境也巨復雜,只要有阻塞操作肯定玩完。Nginx這時已經準備了一個現成的讀取body的非阻塞模式給用戶,就是ngx_http_read_client_request_body方法。
大家看下ngx_http_read_client_request_body方法的原型:
ngx_int_t
ngx_http_read_client_request_body(ngx_http_request_t *r,ngx_http_client_body_handler_pt post_handler);
參數r就是要處理的請求,post_handler則是body接收完成後的回調方法。
所以,在worker進程中,調用ngx_http_read_client_request_body是不會阻塞的,要麽讀完socket上的buffer發現不完整立刻返回,等待下一次EPOLLIN事件,要麽就是讀完body了,調用用戶定義的post_handler方法去處理body。
ngx_http_read_client_request_body提供兩種保存body的方式,一種是把body存儲在內存中,另一種是把body存儲到臨時文件裏。這個臨時文件也有不同的處理方法,一種是請求結束後nginx便清理掉,另外就是永久保留這個臨時文件。例如下面這兩個參數就會設定為每個body都存放到臨時文件裏,並且這個臨時文件在請求結束後不會被刪除:
r->request_body_in_persistent_file = 1;
r->request_body_in_file_only = 1;
nginx讀取請求體