Nginx中如果需要處理請(qǐng)求體禽捆,之后交由其他模塊處理丰包,常用的方式有三種:
- 用一個(gè)content除非的handle模塊接收處理請(qǐng)求體流椒,處理完成后內(nèi)部跳轉(zhuǎn)給其他location。比如nginx-upload-module就是采用這種方法涎跨。
- 注冊(cè)一個(gè)rewrite階段的handle模塊接收處理請(qǐng)求體洼冻。之后按原nginx模塊流程。比如form-input-nginx-module和ngx_json_post_module就是采用這模式
- 注冊(cè)一個(gè)nginx request body filter隅很,使用類似response body filter的方式進(jìn)行處理撞牢。
當(dāng)然這三種方法的適用場(chǎng)景并不相同率碾。這里主要介紹方法3,適用于流式處理請(qǐng)求body數(shù)據(jù)屋彪。
首先所宰,可以用類似注冊(cè)response filter的方式在模塊的postconfigure方法中注冊(cè)request body filter
static ngx_http_request_body_filter_pt ngx_http_next_request_body_filter;
static ngx_int_t ngx_http_example_post_conf(ngx_conf_t *cf)
{
// register input filter
ngx_http_next_request_body_filter = ngx_http_top_request_body_filter;
ngx_http_top_request_body_filter = ngx_http_example_request_body_filter;
return NGX_OK;
}
之后像編寫response body filter一樣完成request body filter方法就可以了。當(dāng)然畜挥,這里需要注意的是仔粥,如果經(jīng)過(guò)這個(gè)filter處理之后改變了原本請(qǐng)求的body的長(zhǎng)度,記得一定要在最后修正頭部的content length蟹但,以免讓之后的模塊或upstream拿到錯(cuò)誤的content length躯泰。
static ngx_int_t
ngx_http_example_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
// ...
if (last_buf_in_this_filter) {
r->headers_in.content_length_n = cry->total_len;
r->headers_in.content_length->value.data = ngx_palloc(r->pool, NGX_OFF_T_LEN);
if (r->headers_in.content_length->value.data == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
r->headers_in.content_length->value.len =
ngx_sprintf(r->headers_in.content_length->value.data, "%O", r->headers_in.content_length_n)
- r->headers_in.content_length->value.data;
}
return ngx_http_next_request_body_filter(r, in);
}
而正常情況(在沒(méi)有第三模塊注冊(cè)request body filter時(shí)),該request body filter的執(zhí)行順序是在ngx_http_request_body_length_filter或ngx_http_request_body_chunked_filter之后執(zhí)行华糖,在這里處理數(shù)據(jù)不用擔(dān)心chunked編碼的問(wèn)題麦向,而對(duì)應(yīng)的ngx_http_next_request_body_filter(也就是注冊(cè)模塊前的ngx_http_top_request_body_filter)正好是ngx_http_request_body_save_filter。當(dāng)然客叉,要注意的诵竭,request body filter只有在真正接收請(qǐng)求body時(shí)才會(huì)被執(zhí)行,比如在handle里請(qǐng)求接收數(shù)據(jù)兼搏,或者向后端upstream轉(zhuǎn)發(fā)請(qǐng)求body時(shí)卵慰。
作者原創(chuàng),轉(zhuǎn)載請(qǐng)注明出處