Nginx的request body filter介紹

Nginx中如果需要處理請求體,之后交由其他模塊處理,常用的方式有三種:

  1. 用一個content除非的handle模塊接收處理請求體,處理完成后內部跳轉給其他location。比如nginx-upload-module就是采用這種方法。
  2. 注冊一個rewrite階段的handle模塊接收處理請求體。之后按原nginx模塊流程。比如form-input-nginx-module和ngx_json_post_module就是采用這模式
  3. 注冊一個nginx request body filter,使用類似response body filter的方式進行處理。

當然這三種方法的適用場景并不相同。這里主要介紹方法3,適用于流式處理請求body數據。

首先,可以用類似注冊response filter的方式在模塊的postconfigure方法中注冊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方法就可以了。當然,這里需要注意的是,如果經過這個filter處理之后改變了原本請求的body的長度,記得一定要在最后修正頭部的content length,以免讓之后的模塊或upstream拿到錯誤的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);
}

而正常情況(在沒有第三模塊注冊request body filter時),該request body filter的執(zhí)行順序是在ngx_http_request_body_length_filter或ngx_http_request_body_chunked_filter之后執(zhí)行,在這里處理數據不用擔心chunked編碼的問題,而對應的ngx_http_next_request_body_filter(也就是注冊模塊前的ngx_http_top_request_body_filter)正好是ngx_http_request_body_save_filter。當然,要注意的,request body filter只有在真正接收請求body時才會被執(zhí)行,比如在handle里請求接收數據,或者向后端upstream轉發(fā)請求body時。

作者原創(chuàng),轉載請注明出處

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容