Skip to content

http output filter module

paulran edited this page Apr 21, 2016 · 1 revision

1. 首先是module,有定义:

ngx_module_t  ngx_http_xxx_filter_module = {..., &ngx_http_xxx_filter_module_ctx, ... };
static ngx_http_module_t  ngx_http_xxx_filter_module_ctx = { ngx_http_xxx_add_variables, ngx_http_xxx_filter_init,  ... };

2. 在 src/http/modules/ngx_http_xxx_filter_module.c 中定义了两个变量:

static ngx_http_output_header_filter_pt  ngx_http_next_header_filter;
static ngx_http_output_body_filter_pt    ngx_http_next_body_filter;

分别指向下一个 header filter module 和下一个 body filter module。

3. filter module 本身提供的接口:

static ngx_int_t ngx_http_xxx_header_filter(ngx_http_request_t *r) { ...; ngx_http_next_header_filter(r); ... }
static ngx_int_t ngx_http_xxx_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { ...; ngx_http_top_body_filter(r, in); ... }

4. filter module 的 init 函数的设计:

static ngx_int_t ngx_http_xxx_filter_init(ngx_conf_t *cf)
{
    ngx_http_next_header_filter = ngx_http_top_header_filter;
    ngx_http_top_header_filter = ngx_http_xxx_header_filter;

    ngx_http_next_body_filter = ngx_http_top_body_filter;
    ngx_http_top_body_filter = ngx_http_xxx_body_filter;

    return NGX_OK;
}

通过全局变量 ngx_http_top_header_filter 和 ngx_http_top_body_filter 来关联所有的 filter。

extern ngx_http_output_header_filter_pt  ngx_http_top_header_filter;
extern ngx_http_output_body_filter_pt    ngx_http_top_body_filter;

filter modules 的初始化顺序决定了 filter module 被调用的前后。

5. Nginx 使用的 http filter module:

编译时,通过 "./configure" 生成的 objs/ngx_modules.c 中有定义。例如:

ngx_module_t *ngx_modules[] = {
    ... ...
    &ngx_http_write_filter_module,
    &ngx_http_header_filter_module,
    &ngx_http_chunked_filter_module,
    &ngx_http_range_header_filter_module,
    &ngx_http_gzip_filter_module,
    &ngx_http_postpone_filter_module,
    &ngx_http_ssi_filter_module,
    &ngx_http_charset_filter_module,
    &ngx_http_userid_filter_module,
    &ngx_http_headers_filter_module,
    &ngx_http_copy_filter_module,
    &ngx_http_range_body_filter_module,
    &ngx_http_not_modified_filter_module,
    NULL
};

它们的调用堆栈示例:

ngx_int_t ngx_http_send_header(ngx_http_request_t *r)
{
    if (r->post_action) {
        return NGX_OK;
    }

    if (r->header_sent) {
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
                      "header already sent");
        return NGX_ERROR;
    }

    if (r->err_status) {
        r->headers_out.status = r->err_status;
        r->headers_out.status_line.len = 0;
    }

    return ngx_http_top_header_filter(r); // start to call filters.
}

6. 各个 http output filter module 的实现分析

Clone this wiki locally