过滤模块简介
执行时间和内容
过滤(filter)模块是过滤响应头和内容的模块,可以对回复的头和内容进行处理。它的处理时间在获取回复内容之后,向用户发送响应之前。它的处理过程分为两个阶段,过滤 HTTP 回复的头部和主体,在这两个阶段可以分别对头部和主体进行修改。
执行顺序
过滤模块的调用是有顺序的且在编译时决定。控制编译的脚本位于 auto/modules 中,当你编译完 Nginx 以后,可以在 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 };
从 write_filter 到 not_modified_filter,模块的执行顺序是反向的。即最早执行的是 not_modified_filter,然后各个模块依次执行。一般情况下,第三方过滤模块的 config 文件会将模块名追加到变量 HTTP_AUX_FILTER_MODULES 中,此时该模块只能加入到 copy_filter 和 headers_filter 模块之间执行。
模块编译
Nginx 可以加入第三方的过滤模块。在过滤模块的目录里,首先要加入 config 文件,文件的内容如下:
ngx_addon_name=ngx_http_example_filter_module HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES ngx_http_example_filter_module" NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_example_filter_module.c"
把名为 ngx_http_example_filter_module 的过滤模块加入,ngx_http_example_filter_module.c 是该模块的源代码。
过滤模块的分析
相关结构体
ngx_chain_t 结构是一个单向链表:
typedef struct ngx_chain_s ngx_chain_t; struct ngx_chain_s { ngx_buf_t *buf; ngx_chain_t *next; };
在过滤模块中,所有输出的内容都是通过一条单向链表所组成。单向链表的设计好处是简单,非阻塞,但是跨链表的内容操作非常麻烦,如果需要跨链表,很多时候只能缓存链表的内容。
单链表负载的就是 ngx_buf_t,该结构体使用非常广泛,该结构体的代码如下: