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的执行顺序是在ngx_http_request_body_length_filter或ngx_http_request_body_chunked_filter之后执行,在这里处理数据不用担心chunked编码的问题,而对应的ngx_http_next_request_body_filter(也就是注册模块前的ngx_http_top_request_body_filter)正好是ngx_http_request_body_save_filter。当然,要注意的,request body filter只有在真正接收请求body时才会被执行,比如在handle里请求接收数据,或者向后端upstream转发请求body时。

作者原创,转载请注明出处

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容